Yii2 错误处理
1 <?php 2 /* 3 Filename: ErrorHandler.php 4 Comment: 重写yii 错误处理信息 5 User: lxd 6 Time: 16/11/24 17:31 7 */ 8 namespace frontend\controllers\errorhandler; 9 10 use frontend\controllers\MainController; 11 use yii\base\ErrorException; 12 13 class ErrorHandler extends \yii\base\ErrorHandler 14 { 15 16 const ERROR_EMAIL = '1209349015@qq.com'; //接收错误信息的邮箱 17 18 /** 19 * 重写 handleError ,让其在非致命错误的时候,程序可以继续执行 20 */ 21 public function handleError( $code, $message, $file, $line ) 22 { 23 if (error_reporting() & $code) { 24 // load ErrorException manually here because autoloading them will not work 25 // when error occurs while autoloading a class 26 if (!class_exists('yii\\base\\ErrorException', false)) { 27 require_once(\Yii::getAlias('@yii/base') . '/ErrorException.php'); 28 } 29 30 $exception = new ErrorException($message, $code, $code, $file, $line); 31 32 // in case error appeared in __toString method we can't throw any exception 33 $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); 34 array_shift($trace); 35 foreach ($trace as $frame) { 36 if ($frame['function'] === '__toString') { 37 $this->handleException($exception); 38 if (defined('HHVM_VERSION')) { 39 flush(); 40 } 41 exit(1); 42 } 43 } 44 45 if( !YII_DEBUG ) { 46 //判断是否属于致命错误 47 if( ErrorException::isFatalError( ['type' => $code] ) ) { 48 //致命错误,抛出异常,让异常类接管 49 throw $exception; 50 }else{ 51 //非致命错误,直接执行 renderException ,记录后继续执行代码 52 $this->renderException( $exception ); 53 } 54 }else 55 throw $exception; 56 57 } 58 59 //return false 不理解,注释掉后,E_USER_ERROR 程序不会终止执行 60 } 61 62 63 64 /** 65 * 重写yii2 的自定义错误信息,全部的error_reporting错误,触发 66 * 67 * Renders the exception. 68 * @param \Exception $exception the exception to be rendered. 69 */ 70 protected function renderException($exception) 71 { 72 $msg = ''; 73 if( $exception instanceof ErrorException ) { 74 $email_msg = '出错了: 时间:[' . date('Y-m-d H:i') . '];错误内容:' . $exception->getMessage() . ';文件名称:' . $exception->getFile() . ';行数:' . $exception->getLine() . "\r\n"; 75 76 //计入log信息 77 error_log( $email_msg, 3, \Yii::getAlias( '@runtime/logs/app_error.log' ) ); 78 79 //程序错误 80 switch( $exception->getCode() ) { 81 case E_ERROR: 82 //如果是严重错误,或者用户抛出的严重错误,那么发邮件处理 83 if( !YII_DEBUG ) 84 error_log( $email_msg, 1, self::ERROR_EMAIL ); 85 86 //统一返回格式。返回json格式信息 87 MainController::SResponse( ['msg' => '服务器返回状态码:500;错误信息:' . $exception->getMessage()], 1, '服务器异常', 9999 ); 88 break; 89 //如果是用户类错误,发送邮件告警,继续执行 90 case E_USER_ERROR: 91 if( !YII_DEBUG ) 92 error_log( $email_msg, 1, self::ERROR_EMAIL ); 93 break; 94 } 95 }else { 96 $http_code = isset( $exception->statusCode ) ? $exception->statusCode : '404'; 97 //返回json格式信息 98 MainController::SResponse( ['msg' => '服务器返回状态码:'. $http_code .';错误信息:' . $exception->getMessage()], 1, '服务器异常', 9999 ); 99 } 100 } 101 }
测试效果:
在登录类里面,trigger_error
1 public function actionLogin() 2 { 3 trigger_error( 'user_error but program not stop', E_USER_ERROR ); 4 if( \Yii::$app->session->has( \Yii::$app->params['usess.id'] ) ) 5 self::SResponse( [], 1, '已登录用户不能进行该操作', '0111'); 6 7 $model = new Register(); 8 $this->_myValidate( $model ); 9 10 if( !$res = $model->login()) { 11 self::SResponse( [], 1, $model->myError['msg'], $model->myError['code']); 12 } 13 14 20 21 self::SResponse( $res ); 22 }
代码正常执行,同时收到提醒邮件