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

Yii предоставляет полноценный функционал обработки ошибок на базе механизма обработки ошибок в РНР 5. В момент поступления пользовательского запроса создается экземпляр приложения, который регистрирует метод handleError для обработки предупреждений и уведомлений, а также метод handleException для обработки не пойманных исключений. Таким образом, если в процессе выполнения приложения возникают предупреждения, уведомления РНР или непойманные исключения, один из обработчиков ошибок получит управление и запустит необходимую процедуру обработки ошибок.

Подсказка: Регистрация обработчиков ошибок осуществляется в конструкторе приложения путем вызова функций РНР set_exception_handler и set_error_handler. Если вы не хотите, чтобы Yii обрабатывал ошибки и исключения, во входном скрипте установите значение false константам YII_ENABLE_ERROR_HANDLER и YII_ENABLE_EXCEPTION_HANDLER.

По умолчанию, метод handleError (или handleException) вызывает событие onError (или onException). Если ошибка (или исключение) не обрабатывается обработчиком события, он обращается за помощью к компоненту приложения errorHandler.

1. Вызов исключений

Вызов исключений в Yii ничем не отличается от вызова обычного исключения РНР. В случае необходимости, вызов исключения осуществляется следующим образом:

throw new ExceptionClass('ExceptionMessage');

Yii определяет три класса для исключений: CException, CDbException и CHttpException. CException — типовой класс исключения. CDbException представляет исключения, вызываемые некоторыми операциями базы данных. CHttpException отвечает за исключения, которые отображаются конечному пользователю, и содержит свойство statusCode, соответствующее коду состояния НТТР. Класс исключения определяет также, каким образом отображается ошибка. Об этом будет рассказано ниже.

Подсказка: Вызов исключения CHttpException — это простой способ сообщить об ошибках, вызванных неверными действиями пользователя. Например, если пользователь указывает в адресе URL неверный идентификатор записи, для отображения ошибки 404 (страница не найдена) мы можем выполнить следующее действие:

// если идентификатора записи не существует
throw new CHttpException(404,'Указанная запись не найдена');

2. Отображение ошибок

В момент, когда компонент приложения CErrorHandler получает ошибку, выбирается соответствующее представление для её отображения. Если предполагается, что сообщение об ошибке должно отображаться конечным пользователям, например CHttpException, то используется представление с именем errorXXX, где XXX соответствует коду состояния НТТР (400, 404, 500 и т.д.). Если же это внутренняя ошибка и отображаться она должна только разработчикам, используется представление с именем exception. В последнем случае будет отображен весь стек вызовов, а также указание на строку возникновения ошибки.

Инфо: Если приложение запускается в производственном режиме, все ошибки, включая внутренние, отображаются с использованием представления errorXXX. Это сделано из соображений безопасности, поскольку стек вызова может содержать важную информацию. В этом случае для выявления причин возникновения ошибки необходимо использовать протокол ошибок.

CErrorHandler осуществляет поиск файла, соответствующего представлению, в следующем порядке:

  1. WebRoot/themes/ThemeName/views/system: папка системных представлений текущей темы оформления;

  2. WebRoot/protected/views/system: папка системных представлений приложения, используемая по умолчанию;

  3. yii/framework/views: папка стандартных системных представлений, предоставляемых фреймворком.

Следовательно, если нам необходимо изменить внешний вид сообщений, мы можем просто создать файлы представлений ошибок в папке системных представлений приложения или темы. Каждый файл представления — это обычный РНР-скрипт, состоящий преимущественно из HTML-кода. Подробнее с этим можно разобраться, просто изучив используемые по умолчанию файлы, расположенные в папке фреймворка с именем view.

3. Управление отображением ошибок в действии контроллера

Yii позволяет использовать действие контроллера для отображения ошибок. Для этого необходимо задать обработчик ошибок в настройках приложения:

return array('components'=>array(
        'errorHandler'=>array(
            'errorAction'=>'site/error',
        ),
    ),
);

Выше мы задали маршрут site/error, ведущий к действию error контроллера SiteController, свойству CErrorHandler::errorAction. Если необходимо, можно использовать другой маршрут.

Код действия error должен выглядеть примерно так:

public function actionError()
{
    if($error=Yii::app()->errorHandler->error)
        $this->render('error', $error);
}

Сначала мы получаем подробную информацию об ошибке из CErrorHandler::error. Если она не пуста — отображаем её в представлении error. Информация, получаемая из CErrorHandler::error является массивом, содержащим следующие данные:

  • code: код ответа HTTP (например, 403 или 500);
  • type: тип ответа (например, CHttpException или PHP Error);
  • message: текст сообщения;
  • file: имя PHP-скрипта, в котором возникла ошибка;
  • line: номер строки, на которой возникла ошибка;
  • trace: стэк вызовов ошибки;
  • source: часть кода, где возникла ошибка.

Подсказка: Проверка CErrorHandler::error на пустое значение делается, т.к. действие error может быть вызвано пользователем напрямую. Так как мы передаём массив $error представлению, он будет автоматически развёрнут в отдельные переменные, поэтому мы можем обращаться к ним напрямую, как $code или $type.

4. Протоколирование сообщений

Если возникает ошибка, то соответствующее сообщение с уровнем error всегда вносится в лог. В случае, если ошибка — результат предупреждения или уведомления РНР, сообщению присваивается категория php, если же ошибка вызвана не пойманным исключением, сообщению присваивается категория exception.ExceptionClassName (в случае CHttpException к категории добавляется код состояния). Для отслеживания ошибок, возникающих в процессе выполнения приложения, можно использовать функционал журналирования.

Be the first person to leave a comment

Please to leave your comment.