Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP exceptions thrown in error handler are not caught by exception handler

Tags:

php

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

set_error_handler
set_exception_handler

The error handler transforms errors to 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");
}

exception handler example:

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

(I think this can not work anyway)

Should this work ?

Or can someone explain why it can not work ?

EDIT:

I made some tests, and it should work.

Exceptions thrown in the ErrorHandler are getting caught by the ExceptionHandler And Errors triggered in the ExceptionHandler are getting processed by the ErrorHandler

Just FYI.

My Problem has to be elsewhere


EDIT:

I Still have not found why the exception thrown in my errorHandler is not caught by my exceptionHandler.

For Example when I have this 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 gets handled by the errorHandler but the exception thrown in the errorHandler gets not handled by the exceptionHandler.

But if I throw an exception at the same place where I trigger an error, this exception gets handled by the exception handler.

(Hope it is somehow understandable what I mean)

I'm clueless here. Any Ideas where I have to look for the Problem?

like image 762
mjspier Avatar asked May 02 '11 13:05

mjspier


1 Answers

This question is over 2 years old, but the OP's observation that some exceptions thrown from an error handler cannot be caught is actually correct:

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();

In the last line, there are actually two errors triggered in short succession:

  1. "Undefined variable: foo" (E_NOTICE)
  2. "Function name must be a string" (E_ERROR)

One would expect errorHandler() to catch the E_NOTICE and throw an Exception, which then gets handled by exceptionHandler(). Since exceptionHandler() never returns, execution should stop there.

But that's not what happens: The errorHandler() does get called and throws its Exception, but before the exceptionHandler() can react, PHP decides to exit due to the fatal E_ERROR.

It's unfortunate, and there's no pretty generic solution that I'm aware of. One thing you could do is to not throw new Exception(...) from your error handler, but directly call exceptionHandler(new Exception(...)). This works as expected, but has the disadvantage that you cannot try .. catch PHP errors anymore.

UPDATE 2014-04-30:

This has apparently been fixed in PHP 5.5 (or possibly 5.4, I can't test that now). $foo and $foo() now behave the same way, they both produce the output exceptionHandler: 'Undefined variable: foo'.

like image 122
Zilk Avatar answered Oct 22 '22 22:10

Zilk