mirror of
https://github.com/yiisoft/yii.git
synced 2026-03-06 16:16:53 +01:00
141 lines
11 KiB
Plaintext
141 lines
11 KiB
Plaintext
Обработка ошибок
|
||
================
|
||
|
||
Yii предоставляет полноценный функционал обработки ошибок на базе механизма
|
||
обработки ошибок в РНР 5. В момент поступления пользовательского запроса
|
||
создается экземпляр приложения, который регистрирует метод [handleError|CApplication::handleError] для
|
||
обработки предупреждений и уведомлений, а также метод [handleException|CApplication::handleException]
|
||
для обработки не пойманных исключений. Таким образом, если в процессе выполнения приложения возникают
|
||
предупреждения, уведомления РНР или непойманные исключения, один из обработчиков ошибок получит управление
|
||
и запустит необходимую процедуру обработки ошибок.
|
||
|
||
> Tip|Подсказка: Регистрация обработчиков ошибок осуществляется в конструкторе приложения путем вызова функций РНР
|
||
[set_exception_handler](http://php.net/manual/en/function.set-exception-handler.php) и
|
||
[set_error_handler](http://php.net/manual/en/function.set-error-handler.php).
|
||
Если вы не хотите, чтобы Yii обрабатывал ошибки и исключения, во [входном скрипте](/doc/guide/basics.entry)
|
||
установите значение *false* константам `YII_ENABLE_ERROR_HANDLER` и `YII_ENABLE_EXCEPTION_HANDLER`.
|
||
|
||
По умолчанию, метод [errorHandler|CApplication::errorHandler] (или [exceptionHandler|CApplication::exceptionHandler])
|
||
вызывает событие [onError|CApplication::onError] (или [onException|CApplication::onException]). Если ошибка (или исключение)
|
||
не обрабатывается обработчиком события, он обращается за помощью к компоненту приложения [errorHandler|CErrorHandler].
|
||
|
||
Вызов исключений
|
||
------------------
|
||
|
||
Вызов исключений в Yii ничем не отличается от вызова обычного исключения РНР.
|
||
В случае необходимости, вызов исключения осуществляется следующим образом:
|
||
|
||
~~~
|
||
[php]
|
||
throw new ExceptionClass('ExceptionMessage');
|
||
~~~
|
||
|
||
Yii определяет два класса для исключений: [CException] и [CHttpException]. Первый является
|
||
типовым классом исключения, а второй отвечает за исключения, которые отображаются конечному пользователю.
|
||
Кроме того, второй класс имеет свойство [statusCode|CHttpException::statusCode], соответствующее
|
||
коду состояния НТТР. Класс исключения определяет также, каким образом отображается ошибка.
|
||
Об этом будет рассказано ниже.
|
||
|
||
> Tip|Подсказка: Вызов исключения [CHttpException] — это простой способ сообщить об ошибках,
|
||
> вызванных неверными действиями пользователя. Например, если пользователь указывает в адресе URL
|
||
> неверный идентификатор записи, для отображения ошибки 404 (страница не найдена) мы можем
|
||
> выполнить следующее действие:
|
||
>
|
||
> ~~~
|
||
> [php]
|
||
> // если идентификатора записи не существует
|
||
> throw new CHttpException(404,'Указанная запись не найдена');
|
||
> ~~~
|
||
|
||
Отображение ошибок
|
||
-----------------
|
||
|
||
В момент, когда компонент приложения [CErrorHandler] получает ошибку, выбирается
|
||
соответствующее представление для её отображения. Если предполагается, что сообщение об ошибке
|
||
должно отображаться конечным пользователям, например [CHttpException], то используется
|
||
представление с именем `errorXXX`, где `XXX` соответствует коду состояния НТТР (400, 404, 500 и т.д.).
|
||
Если же это внутренняя ошибка и отображаться она должна только разработчикам, используется представление
|
||
с именем `exception`. В последнем случае будет отображен весь стек вызовов, а также указание на строку возникновения ошибки.
|
||
|
||
> Info|Инфо: Если приложение запускается в [производственном режиме](/doc/guide/basics.entry#debug-mode),
|
||
все ошибки, включая внутренние, отображаются с использованием представления `errorXXX`. Это сделано из
|
||
соображений безопасности, поскольку стек вызова может содержать важную информацию. В этом случае
|
||
для выявления причин возникновения ошибки необходимо использовать протокол ошибок.
|
||
|
||
[CErrorHandler] осуществляет поиск файла, соответствующего представлению, в следующем порядке:
|
||
|
||
1. `WebRoot/themes/ThemeName/views/system`: папка системных представлений текущей темы оформления;
|
||
|
||
2. `WebRoot/protected/views/system`: папка системных представлений приложения, используемая по умолчанию;
|
||
|
||
3. `yii/framework/views`: папка стандартных системных представлений, предоставляемых фреймворком.
|
||
|
||
Следовательно, если нам необходимо изменить внешний вид сообщений, мы можем просто создать
|
||
файлы представлений ошибок в папке системных представлений приложения или темы. Каждый файл представления —
|
||
это обычный РНР-скрипт, состоящий преимущественно из HTML-кода. Подробнее с этим можно разобраться, просто изучив
|
||
используемые по умолчанию файлы, расположенные в папке фреймворка с именем `view`.
|
||
|
||
|
||
Управление отображением ошибок в действии контроллера
|
||
-----------------------------------------------------
|
||
|
||
Начиная с версии 1.0.6 Yii позволяет использовать [действие контроллера](/doc/guide/basics.controller#action)
|
||
для отображения ошибок. Для этого необходимо задать обработчик ошибок в настройках
|
||
приложения:
|
||
|
||
~~~
|
||
[php]
|
||
return array(
|
||
…
|
||
'components'=>array(
|
||
'errorHandler'=>array(
|
||
'errorAction'=>'site/error',
|
||
),
|
||
),
|
||
);
|
||
~~~
|
||
|
||
Выше мы задали маршрут `site/error`, ведущий к действию `error` контроллера
|
||
`SiteController`, свойству [CErrorHandler::errorAction]. Если необходимо,
|
||
можно использовать другой маршрут.
|
||
|
||
Код действия `error` должен выглядеть примерно так:
|
||
|
||
~~~
|
||
[php]
|
||
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`: часть кода, где возникла ошибка.
|
||
|
||
> Tip|Подсказка: Проверка [CErrorHandler::error] на пустое значение делается, т.к.
|
||
действие `error` может быть вызвано пользователем напрямую. Так как мы передаём
|
||
массив `$error` представлению, он будет автоматически развёрнут в отдельные переменные,
|
||
поэтому мы можем обращаться к ним напрямую, как `$code` или `$type`.
|
||
|
||
|
||
Протоколирование сообщений
|
||
--------------------------
|
||
|
||
Если возникает ошибка, то соответствующее сообщение с уровнем `error` всегда вносится в лог.
|
||
В случае, если ошибка — результат предупреждения или уведомления РНР, сообщению присваивается категория
|
||
`php`, если же ошибка вызвана не пойманным исключением, сообщению присваивается категория
|
||
`exception.ExceptionClassName` (в случае [CHttpException] к категории добавляется
|
||
[код состояния|CHttpException::statusCode]). Для отслеживания ошибок, возникающих в процессе
|
||
выполнения приложения, можно использовать функционал [журналирования](/doc/guide/topics.logging).
|
||
|
||
<div class="revision">$Id: topics.error.txt 2739 2010-12-14 01:50:04Z weizhuo $</div> |