Проверка работоспособности исключения PHP 5.3 — действительно ли PHP выводит внутреннее сообщение об исключении?

#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. Ха-ха, имеет смысл, если самое внутреннее исключение является наиболее подробным (чего у меня нет, что может быть плохо), но также было бы больше смысла, если бы оно печатало «Произошла ошибка при выполнении бла-бла-бла, которая завершилась сбоем во время «внутреннего исключения»». Но спасибо. По крайней мере, я не делаю ничего программно неправильного.