Регистрируйте пойманное исключение с трассировкой стека


Если я не поймаю исключение в PHP, я получу полезное сообщение об ошибке в моем файле error.log с трассировкой стека. Например, если я запущу:

<?php

  function foo() {
    throw new Exception('Oh no!');
  } 

  foo();

?>

Затем я записываю это в свои журналы:

[Ср. 06 марта 10:35:32 2013] [ошибка] [клиент 86.146.145.175] Фатальная ошибка PHP: Неперехваченное исключение "Исключение" с сообщением "О нет!" в /var/www/test.php:4\nstack трассировка: \n#0/var/www/test.php (7): foo()\n#1{основной}\n добавлено/var/www/test.php в режиме онлайн 4

Иногда я хотел бы поймать исключение, но все равно регистрировать эту деталь. Я представляю себе что-то вроде:

<?php

  function foo() {
    throw new Exception('Oh no!');
  } 

  try {
      foo();
  } catch (Exception $e) {
      log_exception($e);
  }

?>

Где log_exception запишет в журнал ошибок что-то в основном в том же формате, что и то, что автоматически записывается для неперехваченного исключения - возможно, буквально идентично, кроме того, что Caught exception вместо PHP Fatal error: Uncaught exception.

Есть ли встроенная функция для регистрации информации об исключениях, подобной этой, или для записи ее в строку? Я представляю себе что-то похожее на traceback.format_exc() в Питон.

Author: Mark Amery, 2013-03-06

4 answers

error_log($e);

Делает то, что вы хотите. Он регистрирует точно то же самое, что было бы зарегистрировано, если бы вы не поймали исключение, за вычетом слова "Неперехваченный" в начале. Он делает это, потому что это то, что Exception возвращает магический метод класса __toString() .

Вы можете сделать это в блоке catch:

try {
    foo();
} catch (Exception $e) {
    error_log("Caught $e");
}

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

set_exception_handler(function($exception) {
    error_log($exception);
    error_page("Something went wrong!");
});
 46
Author: Jay K, 2017-08-11 18:31:25

Вы можете использовать методы из базового класса PHP Exception.

Используйте getMessage для получения сообщения Oh no! и используйте getTraceAsString для получения отформатированной трассировки.

 6
Author: enricog, 2015-11-04 13:40:27

Мы используем Monolog для ведения журнала в нашем приложении. В монологе есть форматировщик, который может печатать трассировки стека. Для регистрации исключений с трассировками мы используем линейный формататор и вызываем на нем функцию includeStacktraces(). (код ниже)

$handler = new \Monolog\Handler\StreamHandler(STDOUT);

$lineFormatter = new \Monolog\Formatter\LineFormatter();
$lineFormatter->includeStacktraces();

$handler->setFormatter($lineFormatter);

$logger = new \Monolog\Logger('root', [$handler]);

try {
    //do some throwing
} catch (Exception $e) {
    //do some logging, add exception to context
    $logger->error($e->getMessage(), ['exception' => $e]);
}
 2
Author: Eelke van den Bos, 2018-03-23 09:53:53

Вы можете использовать http://php.net/manual/en/function.set-exception-handler.php зарегистрировать функцию обратного вызова, которая получит сообщение от $e->GetMessage(); и сбросить его в файл.

 -2
Author: varuog, 2013-03-06 11:00:32