Программирование, веб-кодинг

Обработка ошибок в Yii2. (Errors, ErrorHandler, HttpException)

Обработка ошибок в Yii2. (Errors, ErrorHandler, HttpException)

Конкретный пример

В действии запланирована такая выдача ошибки 403

если всё хорошо, то выполняется что должно выполняться
} else {
    throw new HttpException(403,'Доступно для зарегистрировавшихся');
}

Хочу, чтобы вместо этого пользователя перекидывало на страницу с формой входа. Если использовать yii-user, там можно ещё передать флеш-сообщение с каким-то сопутствующим текстом и оно будет показано перед формой.

если всё хорошо, то выполняется что должно выполняться
} else {
    Yii::$app->session->setFlash('info', 'Курс доступен только для зарегистрированных пользователей. Войдите в личный кабинет или пройдите регистрацию, если ещё не сделали этого.');
    return $this->redirect('/user/login');
}


Обработчик ошибок

Обработчик ошибок включен в Yii2 по-умолчанию. его можно отключить во входном скрипте web/index.php

// Отключение обработчика ошибок Yii2
define('YII_ENABLE_ERROR_HANDLER', false);

Обработчик ошибок подключён как компонент приложения в конфиге

return [
    // ...
    'components' => [
        // ...
        'errorHandler' => [
            'errorAction' => 'site/error',
        ],
        // ...
    ],
    // ...
];

В SiteController.php использовано встроенное действие yii\web\ErrorAction, которое отображает ошибки через представление views/site/error.php

class SiteController extends Controller
{
    // ...
    public function actions()
    {
        return [
            'error' => [
                'class' => 'yii\web\ErrorAction',
            ],
            // ...
        ];
    }
    // ...
}

Представление это можно заменить, указав свойство 'view'

class SiteController extends Controller
{
    // ...
    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);
}


Создать свой обработчик ошибок

Создадим действие site/fault в контроллере SiteController

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';
        return $this->render('custom-error-view', [
            'exception' => $exception,
            'statusCode' => $statusCode,
            'name' => $name,
            'message' => $message
        ]);
    }
}

Тогда в конфиге надо заменить на

return [
    // ...
    'components' => [
        // ...
        'errorHandler' => [
            'errorAction' => 'site/fault',
        ],
        // ...
    ],
    // ...
];

Теперь все ошибки будут обрабатываться новым методом actionFault(). Можно удалить описание ненужного здесь встроенного действия.

class SiteController extends Controller
{
    // ...
    public function actions()
    {
        return [
             // Comment out or remove following error configuration
            // 'error' => [
            //    'class' => 'yii\web\ErrorAction',
            //    'view' => '@app/views/site/custom-error-view.php'
            // ],
            // ...
        ];
    }
    // ...
}

По мотивам – http://nix-tips.ru/yii-2.html