错误处理程序中抛出的PHP异常不会被异常处理程序捕获

时间:2011-05-02 13:54:57

标签: php

我使用以下函数来设置我自己的错误处理程序和异常处理程序。

set_error_handler
set_exception_handler

错误处理程序将错误转换为异常。 (引发新的例外)

但是这些异常并没有被我自己的异常处理程序捕获。

错误处理程序示例:

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

异常处理程序示例:

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

(我认为这无论如何都行不通)

这应该有用吗?

或者有人可以解释为什么它不起作用?

编辑:

我做了一些测试,它应该有效。

错误处理程序中抛出的异常被ExceptionHandler捕获 并且ExceptionHandler中触发的错误正由ErrorHandler

处理

仅供参考。

我的问题必须在别处


编辑:

我仍然没有找到为什么我的exceptionHandler没有捕获我的errorHandler中抛出的异常。

例如,当我在代码中的某处时。

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

错误由errorHandler处理,但errorHandler中抛出的异常不会被exceptionHandler处理。

但是如果我在触发错误的同一个地方抛出异常,则异常由异常处理程序处理。

(希望以某种方式理解我的意思)

我在这里很无能为力。 我需要寻找问题的任何想法吗?

2 个答案:

答案 0 :(得分:5)

这个问题已经超过2年了,但是OP的观察结果是从错误处理程序中抛出的一些异常无法捕获实际上是正确的:

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

在最后一行中,实际上有两个错误在短时间内触发:

  1. “未定义的变量:foo”(E_NOTICE)
  2. “函数名称必须为字符串”(E_ERROR)
  3. 人们会期望errorHandler()捕获E_NOTICE并抛出异常,然后由exceptionHandler()处理。由于exceptionHandler()永远不会返回,执行应该停在那里。

    但事实并非如此:errorHandler()确实被调用并抛出其异常,但在exceptionHandler()可以做出反应之前,PHP决定退出,因为致命的E_ERROR。

    这很不幸,而且我所知道的并没有非常通用的解决方案。您可以做的一件事是不从错误处理程序中throw new Exception(...),而是直接调用exceptionHandler(new Exception(...))。这可以按预期工作,但缺点是你不能再try .. catch PHP错误了。

    更新2014-04-30:

    这显然已在PHP 5.5中修复(或者可能是5.4,我现在无法测试)。 $foo$foo()现在的行为方式相同,它们都会产生输出exceptionHandler: 'Undefined variable: foo'

答案 1 :(得分:0)

我看到两个可能的原因导致你的异常处理程序没有被调用:

  • 没有例外;或
  • 你正在捕捉异常。

如果您向$error_types提供第二个参数set_error_handler,则可能不会针对PHP错误引发异常,这会更改您应该调用自定义处理程序的错误级别

更可能的原因是您已经在try...catch块中捕获了异常。自定义异常处理程序仅针对未捕获的异常

进行调用
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

我还建议您查看内置的ErrorException类:

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