php的Error与Exception捕获问题

来源:互联网 发布:淘宝防排查防举报 编辑:程序博客网 时间:2024/05/17 00:15

最近在项目中前端的php同事发现后台有个php导出的脚本,没有完成就挂掉了,使用try..catch..方式并没有捕获到异常。代码是这样写的

try {    $res = $this->doExprot();} catch (\Exception $e) {    $msg = '导出程序异常,被杀死 ******* 错误信息:' . $e->getMessage() . ' ************';    $res = $e->getTraceAsString();    $this->threadPool->killThread($this->threadPool->getRedisThreadsKeyPre(), $export_log_id, $msg);} finally{    $this->log($supplier_id, $export_log_id, $res);}

日志捕获到的错误为:
这里写图片描述

项目使用的php-7.1.2,框架是larval5.3。根据有日志显示,但是后续捕获日志以及相关逻辑都没有执行,推断程序已经意外中断。到服务器上ps下pid果然没有了。那么为什么没有catch到呢。

进入larval框架下查看Symfony\Component\Debug\Exception\FatalThrowableError源码

class FatalThrowableError extends FatalErrorException{    public function __construct(\Throwable $e)    {        if ($e instanceof \ParseError) {            $message = 'Parse error: '.$e->getMessage();            $severity = E_PARSE;        } elseif ($e instanceof \TypeError) {            $message = 'Type error: '.$e->getMessage();            $severity = E_RECOVERABLE_ERROR;        } else {            $message = $e->getMessage();            $severity = E_ERROR;        }        \ErrorException::__construct(            $message,            $e->getCode(),            $severity,            $e->getFile(),            $e->getLine()        );        $this->setTrace($e->getTrace());    }}

通过对message的判断

local.ERROR: Symfony\Component\Debug\Exception\FatalThrowableError: Cannot use object of type stdClass as array in。。。

知道程序定义错误级别走的为

$message = $e->getMessage();$severity = E_ERROR;

在判定程序错误级别以及错误信息后,执行ErrorException。but。。这位同事just catch Exception。这就是问题点,解决方式很好处理,只需要增加Error的异常捕获就可以。

try {    $res = $this->doExprot();} catch (\Exception $exception) {    $msg = '导出程序异常,被杀死 ******* 错误信息:' . $exception->getMessage() . ' ************';    $res = $exception->getTraceAsString();    $this->threadPool->killThread($this->threadPool->getRedisThreadsKeyPre(), $export_log_id, $msg);} catch(\Error $error) {    $msg = '导出程序异常,被杀死 ******* 错误信息:' . $error->getMessage() . ' ************';    $res = $error->getTraceAsString();    $this->threadPool->killThread($this->threadPool->getRedisThreadsKeyPre(), $export_log_id, $msg);}finally{    $this->log($supplier_id, $export_log_id, $res);}

Error级别定义

Fatal Error:致命错误(脚本终止运行)        E_ERROR         // 致命的运行错误,错误无法恢复,暂停执行脚本        E_CORE_ERROR    // PHP启动时初始化过程中的致命错误        E_COMPILE_ERROR // 编译时致命性错,就像由Zend脚本引擎生成了一个E_ERROR        E_USER_ERROR    // 自定义错误消息。像用PHP函数trigger_error(错误类型设置为:E_USER_ERROR)    Parse Error:编译时解析错误,语法错误(脚本终止运行)        E_PARSE  //编译时的语法解析错误    Warning Error:警告错误(仅给出提示信息,脚本不终止运行)        E_WARNING         // 运行时警告 (非致命错误)。        E_CORE_WARNING    // PHP初始化启动过程中发生的警告 (非致命错误) 。        E_COMPILE_WARNING // 编译警告        E_USER_WARNING    // 用户产生的警告信息    Notice Error:通知错误(仅给出通知信息,脚本不终止运行)        E_NOTICE      // 运行时通知。表示脚本遇到可能会表现为错误的情况.        E_USER_NOTICE // 用户产生的通知信息。

那么再php中Exception和Error有什么区别呢。
在我看来,Error是检测到的这个问题极有可能使程序无法继续运行,而Exception则是虽然有问题但是程序继续运行不受影响。在php7以前的版本中Error类型是不能被捕获的,仅仅可以捕获Exception类型。php7以后Error与Exception都继承了Throwable接口,使得Error被捕获成为可能。
php官方是这么介绍Error的

Error is the base class for all internal PHP errors.Since PHP 7 classname "Error" is predefined and used internally.

Error是所有内部php错误的基本类,并且自从php7以后Error这个类名,您呀就别用了。。。
其他处理错误的方式大家可以看看怎么运用register_shutdown_function,set_error_handler,set_exception_handler这三个神奇的函数,在php7以下的版本也可以捕获Error

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 榨的果汁不甜怎么办 11个月宝宝吃盐怎么办 1岁半宝宝长牙慢怎么办 小孩里面的牙黑怎么办 7个半月宝宝便秘怎么办 2个月婴幼儿便秘怎么办 3个月宝宝不消化怎么办 一天大便二三次不消化怎么办 不消化没胃口几天不大便怎么办? 两个月的宝宝拉绿屎怎么办 肠胃不好消化功能差怎么办 2岁宝宝消化不好怎么办 5天新生儿不拉大便怎么办 七个月宝宝一周不拉屎怎么办 七个月的宝宝消化不良怎么办 七个月宝宝消化不良拉肚子怎么办 宝宝六个月了便秘怎么办 宝宝拉水酸臭味怎么办 50天婴儿不拉屎怎么办 六个月宝宝吃米粉便秘怎么办 纯母乳喂养的宝宝便秘了怎么办 换奶粉拉绿色是怎么办 2个月宝宝发烧怎么办 小宝绿色稀大便怎么办 新生儿吃奶粉大便干燥怎么办 婴儿拉绿色奶瓣怎么办 宝宝吃奶粉大便干燥怎么办 婴儿吃奶粉不大便怎么办 孩子喝奶粉拉大便干怎么办 吃奶粉拉不出来怎么办 一岁半宝宝睡觉抱着睡放不下怎么办 3月大婴儿拉奶瓣怎么办 70多天宝宝便秘怎么办 宝宝喝奶粉上火便秘怎么办 a2奶粉吃了便秘怎么办 两个月宝宝两天没有大便怎么办 婴儿一直拉肚子吃药也不好怎么办 吃奶粉的婴儿便秘怎么办 一个多月小狗便便不成形怎么办 3个月宝宝不拉屎怎么办 好几天不拉大便怎么办