Обробка помилок
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.
Виклик винятків
Виклик винятків у Yii нічим не відрізняється від виклику звичайного винятку РНР. У разі необхідності, виклик винятку здійснюється наступним чином:
throw new ExceptionClass('ExceptionMessage');
Yii визначає три класи для винятків: CException, CDbException та CHttpException. CException — типовий клас винятку. CDbException представляє виняток, викликані деякими операціями бази даних. CHttpException відповідає за винятки, які відображаються кінцевому користувачеві, і містить властивість statusCode, що відповідає коду стану НТТР. Клас винятку визначає також яким чином відображається помилка. Про це буде розказано нижче.
Підказка: Виклик винятку CHttpException — це простий спосіб повідомити про помилки, викликаних невірними діями користувача. Наприклад, якщо користувач вказує в адресі URL невірний ідентифікатор запису, для відображення помилки 404 (сторінка не знайдена) ми можемо виконати наступну дію:
// якщо ідентифікатора запису не існує throw new CHttpException(404,'Зазначений запис не знайдено');
Відображення помилок
У момент, коли компонент додатка CErrorHandler отримує помилку, вибирається відповідне представлення для її відображення.
Якщо передбачається, що повідомлення про помилку повинно відображатися кінцевим користувачам, наприклад CHttpException,
то використовується представлення з імʼям errorXXX
, де XXX
відповідає коду стану НТТР (400, 404, 500 і т.д.).
Якщо ж це внутрішня помилка і відображатися вона повинна тільки розробникам, використовується подання з імʼям
exception
. В останньому випадку буде відображений весь стек викликів, а також вказівку на рядок виникнення помилки.
Інфо: Якщо додаток запускається в виробничому режимі, всі помилки, включаючи внутрішні, відображаються з використанням представлення
errorXXX
. Це зроблено з міркувань безпеки, оскільки стек виклику може містити важливу інформацію. У цьому випадку для виявлення причин виникнення помилки необхідно використовувати протокол помилок.
CErrorHandler здійснює пошук файлу, відповідного представлення, у наступному порядку:
WebRoot/themes/ThemeName/views/system
: папка системних представлень поточної теми оформлення;WebRoot/protected/views/system
: папка системних представлень додатка, яка використовується за замовчуванням;yii/framework/views
: папка стандартних системних представлень, що надаються фреймворком.
Отже, якщо нам необхідно змінити зовнішній вигляд повідомлень, ми можемо просто створити файли представлень помилок в папці системних представлень додатку або теми. Кожен файл представлення — це звичайний РНР-скрипт, що складається переважно з HTML-коду.
Докладніше з цим можна розібратися, просто вивчивши використовувані за замовчуванням файли, розташовані в папці фреймворка з імʼям view
.
Управління відображенням помилок у дії контролера
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
.
Протоколювання повідомлень
Якщо виникає помилка, то відповідне повідомлення з рівнем error
завжди вноситься у лог.
У випадку, якщо помилка — результат попередження або повідомлення РНР, повідомленню привласнюється категорія php
,
якщо ж помилка викликана не спійманим винятком, повідомленню привласнюється категорія
exception.ExceptionClassName
(у випадку CHttpException до категорії додається код стану).
Для відслідковування помилок, що виникають у процесі виконання додатку,
можна використовувати функціонал журналювання.