Yii2 basic: своя страница ошибок. Работа с ErrorHandler, HttpException
Из коробки в Yii2 уже имеется обработчик ошибок (компонент приложения ErrorHandler). По умолчанию он включен. Отключить его можно следующим образом: открыть файл @app/web/index.php
и добавить следующий код:
// Отключить ErrorHandler define('YII_ENABLE_ERROR_HANDLER', false);
Данный компонент подключён в конфиге приложения (@app/config/web.php
):
return [ // ... 'components' => [ // ... 'errorHandler' => [ 'errorAction' => 'site/error', ], // ... ], // ... ];
За рендер самой страницы ошибки отвечает экшен указанный в параметре компонента errorAction.
В контроллере (SiteController) определён ErrorAction
:
public function actions() { return [ 'error' => [ 'class' => 'yii\web\ErrorAction', ] ]; }
Путь к файлу вида для данного экшена @app/views/site/error.php
Изменить представление вывода ошибок можно в свойстве view класса yii\web\ErrorAction
:
public function actions() { return [ 'error' => [ 'class' => 'yii\web\ErrorAction', 'view' => '@app/views/site/custom-error-view.php' ], // ... ]; }
Изменить шаблон для вывода сообщений об ошибках можно 2 способами:
1. Явно указать нужный шаблон в файле представления:
$this->context->layout = 'custom-error-layout';
2. Указать шаблон в методе beforeAction()
контроллера SiteController
public function beforeAction($action) { if ($action->id == 'error') { $this->layout = 'custom-error-layout'; } return parent::beforeAction($action); }
Свой обработчик ошибок
При необходимости, можно создать собственный метод для обработки ошибок. Например, создадим контроллер ErrorController
и метод actionFault()
в нём:
<?php namespace app\controllers; use Yii; use yii\web\Controller; /** * Class ErrorController * Custom error handler */ class ErrorController extends Controller { /** * @return bool|string */ public function actionFault() { $exception = Yii::$app->errorHandler->exception; if ($exception !== null) { $statusCode = $exception->statusCode; $name = $exception->getName(); $message = $exception->getMessage(); // При необходимости меняем шаблон //$this->layout = 'custom-error-layout'; // error/fault return $this->render('fault', [ 'exception' => $exception, 'statusCode' => $statusCode, 'name' => $name, 'message' => $message ]); } return false; } }
Создадим кастомное представление (@app/views/error/fault.php
):
<?php /* @var $this yii\web\View */ /* @var $exception; === стек */ /* @var $statusCode; === код ошибки */ /* @var $name; === имя ошибки */ /* @var $message; === текс ошибка */ use yii\helpers\Html; $this->title = $message; ?> <!-- Выводим то, что нам необходимо --> <div class="error"> <h2 class="statusCode"><?= nl2br(Html::encode($statusCode)) ?></h2> <p class="statusName"><?= nl2br(Html::encode($name)) ?></p> <p class="statusMessage"><?= nl2br(Html::encode($message)) ?></p> <p class="statusException"><?= nl2br(Html::encode($exception)) ?></p> </div>
Далее стилизовать страницу можно как угодно.
Немного поправить конфиг (изменить путь к обработчику):
return [ // ... 'components' => [ // ... 'errorHandler' => [ 'errorAction' => 'error/fault', ], // ... ], // ... ];
Теперь все ошибки будут обрабатываться новым методом actionFault()
. Можно удалить описание ненужного здесь встроенного действия.
class SiteController extends Controller { public function actions() { return [ // Обработкой ошибок теперь занимается другой метод (error/fault) ]; } }
Способов переопределения больше, я же показал один из самых простых.