开发者

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

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

J开发者_开发百科ust 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?


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'.


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

  • There is no exception raised; or
  • You are catching the exception.

It is possible that an exception is not raised for a PHP error, per example, if you provide the second argument $error_types to set_error_handler, which changes for what error levels your custom handler should be called.

The more probable cause is that you are already catching the exception in a try...catch block. Custom exception handlers are only called 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'd also recommend 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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜