Yii2 basic: своя страница ошибок. Работа с ErrorHandler, HttpException

       Yii2      yii2    yii2 basic      1365    
Yii2 basic: своя страница ошибок, работа с ErrorHandler

Из коробки в 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)
    ];
  }
  
}

Способов переопределения больше, я же показал один из самых простых.

Комментарии временно оключены

Поиск

Популярное