Задать вопрос
@Allexio
Программист-путешественник.

Правильно ли я понял централизованную обработку исключений в PHP?

Всем привет!

Пытаюсь разобраться как правильно обрабатывать исключения в веб приложении.. пока остановился на таком варианте. Есть ли тут минусы, может лучше по другому?

Код ниже помещаем в файл типа error-handler.php и инклудим на все необходимые страницы.

// Файл error-handler.php
// Централизованная обработка исключений

ini_set("log_errors", 1);
ini_set("error_log", __DIR__ . "/php-errors.log");

// Уровень ошибок display_errors = 1 используется во время разработки,
// на рабочем сервере установить на 0
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL & ~E_NOTICE);

// Обрабатываем все исключения, возникающие во время работы приложения
function customExceptionHandler($e)
{
    error_log($e);
    http_response_code(500);
    // Если в режиме отладки, то показываем исключения
    if (ini_get('display_errors')) {
        echo $e;
    } else {
        echo "<h1>500 Ошибка сервера.</h1>
              Произошла ошибка на стороне сервера.<br>
              Пожалуйста, попробуйте еще раз позже.";
    }

}

set_exception_handler('customExceptionHandler');


Т.е. в customExceptionHandler мы ловим все возможные исключения, и предпринимаем соответствующие действия.

Иногда возникают ошибки (Error), а не исключения, тогда предлагают добавить такой код, стоит ли?

set_error_handler(function ($level, $message, $file = '', $line = 0)
{
    throw new ErrorException($message, 0, $level, $file, $line);
});


Т.е. ошибку меняем на исключение, и уже обрабатываем опять же в нашем customExceptionHandler.

Буду благодарен за любые комменты )
  • Вопрос задан
  • 512 просмотров
Подписаться 6 Простой 8 комментариев
Решения вопроса 1
FanatPHP
@FanatPHP
Чебуратор тега РНР
В целом правильно, неплохая проработка материала.
У меня есть только пара замечаний, не относящихся напрямую к централизованному обработчику.

  • error_reporting(E_ALL & ~E_NOTICE); делать не стоит. Если только не приходится работать с адовым легаси, которое сыпет нотисами, лучше отлавливать все ошибки. Учитывая же что в 8-ке обращение к несуществующей переменной станет не нотисом а предупреждением, такая конструкция со временем станет бессмысленной. что означает - ошибки надо исправлять, а не замалчивать.
  • ini_set("error_log", __DIR__ . "/php-errors.log"); будет не очень хорошей идеей, если файл error-handler.php выше корня веб-сервера. Ошибки надо прятать подальше.
  • ini_set('display_startup_errors', 1); - это какая-то дичь, которая кочует из руководства в руководство. Никто никогда этих стартап еррорс не видел, но многие старательно пишут это заклинание у себя в коде. Это по-любому связано с настройкой сервера, и в отладке ошибок поможет примерно ничем.
  • само по себе задание настроек через ini-set ненадежно. Ошибка может случиться до того, как РНР прочитает эту команду. Задавать надо в конфигурации веб-сервера.
  • в теории можно добавить флаг или автоматическую проверку на джейсон запрос. и соответственно кодировать ответ в джейсон. Но это только для криовруких фронтендеров, которые не умеют читать НТТР статусы, а ждут что им все разжуют в джейсоне, и без error: true они не поймут, что была ошибка
  • стек вызовов может быть довольно длинным, и раздувать логи. Можно подумать о более укороченном варианте.


Вообще всё зависит от задач. Например все современные фреймворки в режиме разработки выдают развесистую страницу с отчетом об ошибке, которая включает в себя и кусок кода вокруг строи, на которой произошла ошибка.
Но как именно базовый обработчик, необходимый минимум - вполне годно.

Я только не понял, почему вопрос про error_handler. Что именно смущает?
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы