PHP exceptions handled by the error handler do not fall into the exception handler

I use the following function to install my own error handler and exception handler.

set_error_handler set_exception_handler 

An error handler converts errors to an exception. (throws a new exception)

But these exceptions are not caught by my own exception handler.

Error handler example:

 function errorHandler($errno, $errstr, $errfile, $errline, $errcontext) { throw new Exception("this was an error"); } 

An example of an exception handler:

 function exceptionHandler($e){ // don't get here when exception is thrown in error handler Logger::logException($e); } 

(I think this will not work)

If it works?

Or can someone explain why it cannot work?

EDIT:

I did some tests and it should work.

The exceptions thrown in the ErrorHandler get into the ExceptionHandler. And the errors raised in the ExceptionHandler are handled by the ErrorHandler.

Just FYI.

My problem should be elsewhere


EDIT:

I still have not found why the exception thrown in my errorHandler did not fall into my Handler exception.

For example, when I have it somewhere in the code.

 trigger_error("this is an error"); // gets handled by the errorHandler throw new Exception("this is an exception"); // gets handler by the exceptionHandler 

The error is handled by errorHandler, but the exception raised by errorHandler is not handled by the Handler exception.

But if I throw an exception in the same place where I throw the error, this exception is handled by the exception handler.

(I hope this is somehow clear what I mean)

I am ignorant here. Any ideas I should look for a problem in?

+4
source share
2 answers

This question is older than 2 years, but the observation by OP that some exceptions thrown from the error handler cannot be caught is actually true:

 function errorHandler($errno, $errstr, $errfile, $errline) { throw new Exception($errstr); } function exceptionHandler($e) { echo "exceptionHandler: '", $e->getMessage(), "'\n"; } set_error_handler("errorHandler"); set_exception_handler("exceptionHandler"); // this works as expected $a = $foo; // this does not $a = $foo(); 

The last line has two errors caused by a short sequence:

  • "Undefined variable: foo" (E_NOTICE)
  • "Function name must be a string" (E_ERROR)

You can expect errorHandler() catch E_NOTICE and throw an exception, which is then handled by exceptionHandler() . Since exceptionHandler() never returns, execution should stop there.

But this is not what happens: errorHandler() raises a call and throws an exception, but before exceptionHandler() can respond, PHP decides to exit because of the fatal E_ERROR.

This is sad, and there is no fairly general solution that I know of. The only thing you could do is not throw new Exception(...) from the error handler, but directly call exceptionHandler(new Exception(...)) . This works as expected, but has the disadvantage that you can no longer try .. catch PHP errors.

UPDATE 2014-04-30:

This seems to have been fixed in PHP 5.5 (or maybe 5.4, I can't check it now). $foo and $foo() now behave the same, both of them output exceptionHandler: 'Undefined variable: foo' .

+5
source

I see two possible reasons why your exception handler is not called:

  • Excluded exception; or
  • You avoid the exception.

It is possible that an exception does not occur for a PHP error, for example, if you provide the second argument $error_types to set_error_handler , which changes for those error levels that the user-defined handler should be called.

The more likely reason is that you already caught the exception in the try...catch . Custom exception handlers are called only for uncaught exceptions :

 function errorHandler($errno, $errstr, $errfile, $errline, $errcontext) { throw new Exception("this was an error"); } function exceptionHandler($e) { echo 'exceptionHandler'; } set_error_handler('errorHandler'); set_exception_handler('exceptionHandler'); try { file_get_contents('foo'); } catch (Exception $e) { echo $e->getMessage(); // exceptionHandler() not called } file_get_contents('foo'); // exceptionHandler() is called 

I also recommend that you take a look at the built-in ErrorException class:

 function errorHandler($errno, $errstr, $errfile, $errline) { throw new ErrorException($errstr, 0, $errno, $errfile, $errline); } 
0
source

All Articles