#exception-handling #php-5.3
#исключение #php-5.3
Вопрос:
Я думаю, что это немного странно.
Я запускаю скрипт, который запускает программу. Я сохраняю последний вывод в переменной. Если программа или мой скрипт по разным причинам вызывают исключение в скрипте, я перехватываю исключение, добавляю журнал ошибок и повторно загружаю его. Несколькими уровнями выше я снова перехватываю его, регистрирую общее сообщение и повторно загружаю его, чтобы завершить работу скрипта.
Однако, когда командная строка PHP завершает работу, кажется, что в трассировке стека печатается только сообщение о внутреннем исключении, потому что там нет упоминания о моем сообщении. Там даже написано «Неперехваченное исключение», которое является внутренним исключением, которое я создаю при тестировании, в то время как внешнее исключение является пользовательским типом. GetMessage () возвращает полное сообщение, как и ожидалось.
PHP Fatal error: Uncaught exception 'Exception' with message 'This is a test error message.' in /home/x/Documents/project/file.php:14
Трассировка стека:
Я сумасшедший, это ожидаемое поведение? Должен ли я идти спать?
Обновить:
На «корневом» уровне у меня есть это:
catch(Exception $e)
{
$access->logError($e->getMessage());
print 'Actual error: ' . $e->getMessage() . "n";
print get_class($e);
throw $e;
}
оператор print выводит реальное сообщение, которое я ожидаю, aggregate. throw $ e выдает сообщение о внутреннем исключении… print get_class($e)
выводит CustomException…
Это объявление CustomException:
class CustomException extends Exception
{
function __construct($message, $prev)
{
parent::__construct($message, -1, $prev);
}
}
Вот как это используется:
catch(Exception $e)
{
$message = $e->getMessage() . $logString;
$resultReporter->reportError($message);
$e = new CommandException($message, $e);
$throw e;
}
Комментарии:
1. Вы уверены, что действительно перехватываете внутреннее исключение? Возможно, глупый вопрос, но может быть, это единственное исключение, которое он фактически обрабатывает внутри..
2. @rudi Это хороший вопрос, смотрите Мое обновление. Я ожидаю обнаружить, что я совершаю какую-то ошибку…
3. Только что просмотрел ваше обновление, я немного сбит с толку. Вы говорите, что ваше внешнее исключение другого типа, но вы создаете оригинал
Exception
? Я думаю, что, возможно, я что-то упускаю! Или вы просто изначально не создаете внешнее исключение (что предполагает ваш код).4. Я вообще не вижу внешнего исключения 😕
5. @rudi Ну, это мой внешний блок catch- где я перехватываю все исключения (и затем повторно собираю). Смотрите обновление еще раз 🙂 спасибо!
Ответ №1:
После всего этого оказывается, что, я думаю, это ожидаемое поведение.
Похоже, что PHP работает в обратном направлении вверх по стеку исключений, когда у него есть возможность его отобразить.
Смотрите следующий вывод:
Rudis-Mac-Pro:~ rudi$ php ex.php
PHP Fatal error: Uncaught exception 'Exception' with message 'I'm an inner exception' in /Users/rudi/ex.php:3
Stack trace:
#0 {main}
Next exception 'Exception' with message 'I'm the outer exception' in /Users/rudi/ex.php:6
Stack trace:
#0 {main}
Next exception 'Exception' with message 'I'm the reeally outer exception' in /Users/rudi/ex.php:8
Stack trace:
#0 {main}
thrown in /Users/rudi/ex.php on line 8
Это было создано на основе довольно простого кода:
<?php
try {
throw new Exception("I'm an inner exception");
} catch(Exception $ex) {
try {
throw new Exception("I'm the outer exception", -1, $ex);
} catch(Exception $iex) {
throw new Exception("I'm the reeally outer exception", -1, $iex);
}
}
Вероятно, это делается для того, чтобы разработчик мог получить лучшее представление о том, что происходит на самом деле, а не в абстрактном виде. Если подумать, в этом есть смысл ^_^
Теперь иди спать 😉
Комментарии:
1. Ха-ха, имеет смысл, если самое внутреннее исключение является наиболее подробным (чего у меня нет, что может быть плохо), но также было бы больше смысла, если бы оно печатало «Произошла ошибка при выполнении бла-бла-бла, которая завершилась сбоем во время «внутреннего исключения»». Но спасибо. По крайней мере, я не делаю ничего программно неправильного.