Hello!
The error handling process in Yii was not completely transparent to me from the very first days of using this framework. Even despite the presence in the documentation of a special section
Error Handling . In what cases what view is used, how does ajax or debug mode affect, why do I need errorAction, what are the differences when handling exceptions?
In the end, after digging into the documentation and the source code of the framework, I drew a visual error-handling scheme, which personally turned out to be very useful for me and probably will be useful to someone else.
Under the cut scheme itself and some comments to it.
0. Error levels
So, standardly, Yii handles only errors of the
warning and
notice level, as well as
uncaught exceptions . To handle fatal errors you need to use register_shutdown_function (about this at the end of the article).
1. Let's go!
In the event of a warning or uncaught exception, Yii will process them if two constants are set respectively:
YII_ENABLE_ERROR_HANDLER = true YII_ENABLE_EXCEPTION_HANDLER = true
Both errors and exceptions are handled in Yii in a similar scenario. But there are certain differences that I will mention.

')
2. Logging
First of all, the error or exception information is written to the log - the function
Yii :: log () .
3. Call event
Next, the
onError (
onException ) event is
called . If there is a custom handler for these events, then it is called, performs the necessary actions, and can stop further event processing (by setting
event-> handled =
true ). You can hang the handler like this:
$app->onError=function($event) { ... }
or via the attachEventHandler () method.
4. Connection ErrorHandler
If event processing continues (
event-> handled =
false ), the standard component of the yii application
ErrorHandler comes into play (by default it is always not null). It calls the corresponding
handleError () or
handleException () method. Inside these similar methods there is an important distinction between error and exception (available in the current version of Yii 1.1.9):
- In handleError () , the type of the request is checked (ajax or not) and the application mode (constant YII_DEBUG)
- The handleException () checks the type of the exception (CHttpException or CException) and the application mode (constant YII_DEBUG)
Depending on this, either the simplest html error output via app-> displayError (), or the cunning function
render () of the ErrorHandler component is called.
Previously, ajax check was also in handleException (), but in 1.1.9 it was removed, which makes it more convenient to handle exceptions on ajax requests — for example, to return json.
5. Cunning rendering in ErrorHandler
I call the ErrorHandler-> render () function “tricky” because it works a little differently than the controller's usual rendering:
- If YII_DEBUG = true, it is started with the “exception” parameter:
Render "exception.php" - displays detailed debugging information, both for errors and for exceptions - If YII_DEBUG = false and also for a CHttpException, it is run with the “error” parameter:
but. If errorAction is set, it is executed and displays a custom error mapping.
b. If errorAction is not set, it tries to call view errorXXX.php , where is http exception code (always 500 for errors)
at. If view errorXXX.php is not found, then tries to call universal error.php
The view search occurs sequentially in:
1. themes / ThemeName / views / system
2. protected / views / system
3. framework / views
6. Custom error display
In the case of an established
errorAction (for example, “site / error” in the config), this method, I repeat, is used to custom display errors and exceptions in production mode. It is convenient to make a different conclusion for ajax and non-ajax requests. Also note that here the output can be carried out in the overall layout of the application through
views / site / error.php (as opposed to
views / system / errorXXX.php , which contain the full html code of the page).
Afterword: Handling Fatal Errors
And what about the fatal errors? Their interception through the
register_shutdown_function is currently not implemented in Yii. The solution I use now in projects is:
1. When the application is initialized, register the shutdown handler.
2. In the handler, check for the error and its level in
error_get_last () . If the error has already been processed, NULL will return.
3. Run the entire processing mechanism via
app-> handleError () , i.e. close to the beginning of the scheme
When using
error_get_last (), it is important to note that this function ignores the error_reporting directive and the @ character before the operator, i.e. may contain E_NOTICE that are not visible and not processed (for example, calling @session_start () when sessions are running).
Therefore, in the handler, I check only fatal errors.
I also set
errorAction = null - then, as can be clearly seen from the diagram, the system error.php view will be shown, which is safer than running another controller action, where the probability of a repeated error is higher:
class WebApplication extends CWebApplication { protected function init() { register_shutdown_function(array($this, 'onShutdownHandler')); parent::init(); } public function onShutdownHandler() {
Conclusion
In my opinion, error handling in Yii is not very simple, but it has a lot of flexibility. I am pleased to listen to your comments and suggestions.
Thank you for attention!
UPD:Laid out the scheme
in PDF format