yii2错误处理必须在config/web.php的components中配置errorhandler组件,erroraction值需为合法路由且对应控制器存在actionerror方法并返回视图;推荐使用yii\web\erroraction类自动渲染@views/site/error.php。

errorHandler 必须在 config/web.php 的 components 里配
Yii2 的错误分发机制只认应用级 errorHandler 组件配置,写在控制器、行为或模块里全无效。常见踩坑是把 'errorAction' => 'site/error' 放进 Controller::behaviors() 或 actions() —— 这些地方根本不参与错误捕获流程。
正确写法是在 config/web.php 的 'components' 数组中声明:
'errorHandler' => [
'errorAction' => 'site/error',
],
注意:errorAction 值必须是合法路由格式(controller/action),不能带模块前缀,除非你额外配了 'route' 属性;site 对应的控制器必须存在,且其 actionError() 方法要返回视图,不能只是抛异常。
site/error 动作必须返回视图,不能只 throw Exception
很多开发者以为只要写了 'errorAction' => 'site/error' 就完事,结果 404 或 500 时页面空白或跳默认调试页。根本原因是 SiteController::actionError() 没正确实现。
最稳妥的做法是用 Yii 自带的 yii\web\ErrorAction 类:
public function actions()
{
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
];
}
它会自动渲染 @app/views/site/error.php,且确保 $exception 和 $statusCode 变量可用。如果手写 actionError(),必须显式返回视图:
- 不能只写
throw new \Exception(...) - 不能漏掉
return $this->render('error', [...]) - 开发环境(
YII_DEBUG=true)下,未配errorAction会强制显示调试页,此时配置看似“不生效”
视图文件名和路径有硬性约定
Yii2 不会动态猜路径:errorAction 中的 controller 名直接决定视图目录。比如设成 'errors/panic',就必须有 @app/views/errors/error.php,而不是 panic.php 或 @app/views/site/panic.php。
视图里能直接访问的变量只有两个:$exception 和 $statusCode。别指望 $model 或其他控制器传参自动带进来。
调试时可在视图开头加:
<?php var_dump($exception ? $exception->getMessage() : 'no exception'); ?>
确认是否真进了这个视图。另外,error.php 文件名不能改 —— 框架源码里写死的,不是靠配置项控制的。
404 等状态码需在 actionError 里手动分支处理
errorAction 是统一入口,不区分 HTTP 状态码。想让 404 显示不同样式或逻辑,必须在 actionError() 里判断异常类型:
public function actionError()
{
$exception = Yii::$app->errorHandler->exception;
if ($exception instanceof \yii\web\NotFoundHttpException) {
return $this->render('error-404');
}
return $this->render('error');
}
注意:\yii\web\NotFoundHttpException 是 404 的标准异常类,别用字符串匹配 $exception->getName() —— 容易错判;$exception->statusCode 在某些中间件后可能不准,以实例类型为准更可靠。
容易被忽略的是:如果用了模块(如 admin),而错误页想放在模块内,光改 errorAction 不够,还得在配置里加 'route' => 'admin/site/error',否则仍走应用级路由查找。











