Исключение исключения в обработчике исключений
У меня есть 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);
}
Ответ 5
От http://www.php.net/manual/en/function.set-exception-handler.php#88082
Я читаю:
Другим решением является восстановление обработчика ошибок в начале обработчика исключений.
Вы пробовали это?