起因
Yii2框架,在dev环境下时,错误提示是很友好的,但是,如果我们的代码在线上或者在预发布环境上,有时我们不需要将错误显示的那么明显,当然这时我们可以设置环境为prod,这样就不会有错误提示了,但是一旦出了错误,对于开发人员的排查也就比较耗时耗力了,这时,如果程序出错了,便能给开发人员发送一个邮件,告诉开发人员用户的请求地址,请求参数,错误文件,错误的行数,这样也就可以让开发人员在第一时间解决bug,而展示给用户的仅仅是一条我们定义的错误提示,这样是不是会更好呢?
errorHandler组件设置
Yii2为我们提供了errorHandler组件,我们只需要设置一下当出现错误的时候,应该路由到的控制器即可,在main.php或main-local.php中的components中添加
1 | 'errorHandler' => [ |
其次,开启errorHandler 这个组件,需要,关闭debug,同时环境切换的dev下,即在index.php中,将YII_DEBUG和YII_ENV 定义如下
1 | defined('YII_DEBUG') or define('YII_DEBUG', false); |
最后,假如我们将错误处理交给SiteController下actionError() (site/error)这个方法处理,请保证SiteController或者SiteController的父类控制器里面没有下面的内容
1 | public function actions() |
上面的 actions 方法会将actionError()这个方法重新指向 yii\web\ErrorAction 。
将错误信息用邮件发给开发人员
Yii2框架本身的错误提示页面比较友好,所以我便将页面内容拿过来,并做了一点修改。
首先新建一个error对应view模板页面(views/site/error.php),将Yii2本身的错误异常处理页面模板exception.php拷贝过来并修改,相信各位 这点简单的操作 肯定不是什么问题的。
将actionError()修改如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27public function actionError()
{
http_response_code(200);
$exception = Yii::$app->errorHandler->exception;
$statusCode = Yii::$app->response->statusCode;
// 过滤404
// 此时在 file_put_contents的时候,由于jquery.map.js不存在而报404的错误
if ($statusCode != 404) {
$exception_key = Yii::$app->params['ExceptionMailList'];
$request_url = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$params = json_encode(Yii::$app->request->post());
$content = $this->renderPartial('exception', ['exception' => $exception,
'handler' => Yii::$app->errorHandler,
'request_url' => $request_url,
'params' => $params
]);
foreach (Yii::$app->params['ExceptionNotifyList'] as $email) {
Email::begin()->setType('exception')
->setEmail($email)
->setUsername('lixiaoyu')
->setValue('content', $content)
->send();
}
}
return FunctionHelper::errorJson("An internal server error occurred");
}上面代码仅仅是渲染异常页面,然后获取渲染后的页面,并作为邮件内容发送给设置的开发人员的邮箱,这样,便能在第一时间收到异常信息并处理了。