Handling Php Errors

When handling a PHP error, Yii will always end the app, regardless of the type of error message. This means that even PHP notices will kill your app (unless you change your error_reporting level). Personally, I would like to be able to process all PHP errors, but exit only on most severe ones. So if it is a notice, I would just log it and move on, if it is a warning, I might email it to developers and move on, etc.

One solution might be to end the app ONLY if error event was not handled, so we would add the following before line 816 of CApplication:




if($event->handled)

	return false; //PHP error handling takes over when false is returned



Also, you should perhaps perform logging only when event was not handled (line 800):




if(!$event->handled)

{

	//log here and not on line 793

	Yii::log($log,CLogger::LEVEL_ERROR,'php');

	// try an error handler

	...




However, there is still the question of handling the most severe PHP errors. PHP manual says:

It seems that the only way to handle these errors is by registering a shutdown function and then examining the return value of error_get_last(). Could CApplication register a shutdown function which would perform a similar type of error handling as in handleError() method? That way, if I define my own error handler for PHP errors, that handler would be called even for the most severe types of PHP errors, such as E_ERROR or E_PARSE. This is how it might look like:




public function handleSevereError()

{

	$error = error_get_last();

	if ($error)

	{

		Yii::import('CErrorEvent',true);

		$event=new CErrorEvent($this,$error['type'],$error['message'],$error['file'],$error['line']);

		$this->onError($event);

	}

}



And in initSystemHandlers(), you would simply add:




register_shutdown_function(array($this, 'handleSevereError'));



Thoughts and ideas are welcome.

You might be interested in this (although this will be Yii2 only I guess): http://www.yiiframework.com/forum/index.php/topic/40561-throwing-exceptions-when-php-errorswarnings-occur/

P.S.: This is how I solve scenarios like that in some console apps: http://verysimple.com/2010/11/02/catching-php-errors-warnings-and-notices/

Good to know that Yii 2.0 will solve this issue, but it would be nice to fix it in current version as well. To me it seems like a very easy fix, provided that it doesn’t break anything:




if($event->handled)

        return false



Can you create a pull-request at github duplicating description? Definitely should be reviewed by more people.

Is there anything more complicated than git? If so, please switch to that. I’d love to help, but this is ridiculous. Every time I need to do anything with git, it takes me forever. It should have been named geek. Does anyone have simple, easy-to-follow instructions on forking and sending pull requests? The stupid thing is driving me crazy!

Added a pull request here: https://github.com/yiisoft/yii/pull/2203

Here - this page is written for guys like you or me:

http://rogerdudler.github.com/git-guide/

It should have been named ‘grit’ instead of ‘git’ … ;)

Pull request was denied. However, I still think that PHP error handling in Yii needs to be addressed in some way. Sure you could do this:


error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);

and Yii will no longer exit on minor errors. But you will also be completely unaware of any possible problems with your code. What you need is a setup where all errors are logged, but only the most severe errors cause the app to exit. Then you can go through the logs periodically and see if there’s anything that you should fix in your code. If some silly notice is making too much noise, you can suppress it using @.

So let me suggest another option. What if we add a new property to CApplication, say we call it $phpErrorReportingLevel. If left blank, Yii will initialize it to the current value of error_reporting(). Then, in CApplication::initSystemHandlers(), you use this value when setting error handler:


set_error_handler(array($this,'handleError'),$this->phpErrorReportingLevel);

(Note that the order of initialization in constructor would need to be changed, so that app is configured before setting error handler).

So here’s what we can do now:

  1. set PHP error reporting to report all errors (but only to log them, not display them):

error_reporting(E_ALL);

ini_set('display_errors', 0);

ini_set('log_errors', 1);

ini_set('error_log', '/path/to/logfile');

  1. configure Yii to handle only severe errors (in config file):

'phpErrorReportingLevel' => E_ALL & ~E_NOTICE & ~E_WARNING,

The effect would be that minor errors are logged to the specified log file (leaving the client unaware of any problems), whereas major errors are handled by Yii (halting the application and displaying an error message to the client).

<offtopic>@jacmoe: thanks, great guide. I finally understand why you need to do 3 things (add, commit and push) to perform what in SVN is a single action (svn commit).</offtopic>

…and here’s the pull request for the previously suggested change: https://github.com/yiisoft/yii/pull/2207

…and it was instantly rejected. I give up. Guess I will have to wait for 2.0.