Обробка помилок =============== 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`. За замовчуванням, метод [handleError|CApplication::handleError] (або [handleException|CApplication::handleException]) викликає подію [onError|CApplication::onError] (або [onException|CApplication::onException]). Якщо помилка (або виняток) не обробляється обробником події, він звертається по допомогу до компоненту додатка [errorHandler|CErrorHandler]. Виклик винятків --------------- Виклик винятків у Yii нічим не відрізняється від виклику звичайного винятку РНР. У разі необхідності, виклик винятку здійснюється наступним чином: ~~~ [php] throw new ExceptionClass('ExceptionMessage'); ~~~ Yii визначає три класи для винятків: [CException], [CDbException] та [CHttpException]. [CException] — типовий клас винятку. [CDbException] представляє виняток, викликані деякими операціями бази даних. [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`. Управління відображенням помилок у дії контролера ------------------------------------------------- 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).