Исключение исключения в обработчике исключений

У меня есть script с обработчиком исключений. Этот обработчик исключений очищает пару соединений до выхода script после исключения.

Я хотел бы перебросить исключение из этого обработчика исключений, чтобы обработать его собственным обработчиком исключений PHP, где ошибка записывается в журнал ошибок PHP или по умолчанию, как это задано в PHP.ini.

К сожалению, это не похоже на возможность, описанную здесь:

http://www.php.net/manual/en/function.set-exception-handler.php#68712

Вызвать Неустранимая ошибка: Исключение брошено без фрейма стека

Есть ли другой способ, чтобы пузырить ошибку в стеке, чтобы PHP обрабатывал ее после того, как обработчик исключений завершил очистку?

Ответ 1

Вы не можете повторно выбрасывать из обработчика исключений, однако есть и другие места, которые вы можете. Например, вы можете отменить повторный бросок от обработчика, инкапсулируя вещи в собственный класс, а затем использовать функцию __destruct() (PHP 5.3, Demo):

<?php

class ExceptionHandler
{
    private $rethrow;
    public function __construct()
    {
        set_exception_handler(array($this, 'handler'));
    }
    public function handler($exception)
    {
        echo  "cleaning up.\n";
        $this->rethrow = $exception;
    }
    public function __destruct()
    {
        if ($this->rethrow) throw $this->rethrow;
    }
}

$handler = new ExceptionHandler;

throw new Exception();

Поместите это в свой журнал ошибок:

[29-Oct-2011 xx:32:25] PHP Fatal error: Uncaught exception 'Exception' in /.../test-exception.php:23
Stack trace:
#0 {main}
thrown in /.../test-exception.php on line 23

Ответ 2

Просто поймайте исключение и запишите сообщение самостоятельно, затем снимите его.

try {
    $foo->doSomethingToCauseException();
} catch (Exception $e) {
    error_log($e->getMessage());
    throw $e;
}

Если вы пузыритесь вверх и PHP не может обрабатывать, это приведет к неперехваченному исключению.

Ответ 3

Вызвать Неустранимая ошибка: Исключение брошено без фрейма стека

Эта ошибка означает, что ваше исключение выбрано из кода, который не является частью script (насколько известно PHP). Примеры такого кода включают настраиваемый обработчик исключений с set_exception_handler() и любым методом деструктора класса. Нет выбора, кроме как НЕ выбрасывать исключение из такого кода.

Если вам нужна встроенная обработка ошибок PHP, я бы предложил вам вместо trigger_error(). Он должен регистрировать ошибку, если у вас нет настраиваемого обработчика ошибок, и вы используете подходящий тип ошибки. Например, E_USER_ERROR должен быть хорошим.

Ответ 4

Просто снимите исключение как исключение RunTimeException, и оно будет содержать stacktrace:)

try {
    // bad exception throwing code
} catch (Exception $e) {
    throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
}