Skip to content
Aleksey Perevoshchikov edited this page Mar 19, 2017 · 37 revisions

Быстрое подключение

Если вы хотите быстро подключить ErrorHandler к вашему скрипту, например для теста, достаточно добавить строку следующего вида:

require__DIR__.'/vendor/peraleks/error-handler/src/register_error_handler.inc';

В случае, если вы произвели установку из архива, скорректируйте путь к файлу register_error_handler.inc соответствующим образом.

ErrorHandlerне может обработать ошибкуE_COMPILE_ERRORи исключениеParseError, если они были сгенерированы в том же файле, гдеErrorHandlerбыл подключен.


Стандартное подключение

  • Скопируйте папку /vendor/peraleks/error-handler/src/Config в удобное для вас место.
  • Скопируйте код из файла /vendor/peraleks/error-handler/src/register_error_handler.inc в ваш индексный файл.
  • Скорректируйте пути к файлу загрузчика классов и конфигурации.

Например, если у вас получилась такая структура папок:

  • Application_folder
    • Config
    • vendor
    • index.php

Код должен выглядеть так:

require__DIR__.'/vendor/peraleks/error-handler/src/Autoload/ClassLoader.php';
(new \Peraleks\ErrorHandler\Autoload\ClassLoader);
\Peraleks\ErrorHandler\Core\ErrorHandler::instance(__DIR__.'/Config/main.php');

Логирование перехваченных исключений

Часто возникает потребность просто залогировать ошибку, пойманную конструкцией try {} catch ().
Для этого можно воспользоваться методом Peraleks\ErrorHandler\Core\ErrorHandler::instance()->exception(), передав первым параметром объект \Throwable, а вторым - строку, которую уведомители воспримут как тип ошибки, и отобразят соответствующим образом.

Например:

usePeraleks\ErrorHandler\Core\ErrorHandler;
try {
$dbh = new \PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
} catch (\Throwable$e) {
ErrorHandler::instance()->exception($e, 'Database connection error');
// ... далее какая-то логика обработки ошибки 
}

HtmlNotifier отобразит это исключение так:

Но вы спросите: "Какое отношение к логированию имеет HtmlNotifier, выводящий ошибку в браузер?"

И действительно - никакого.

Всё дело в архитектуре ErrorHandler.

В задачи метода Peraleks\ErrorHandler\Core\ErrorHandler::instance()->exception() не входит логирование. Этот метод вообще назначен глобальным обработчиком исключений при помощи функции set_exception_handler(). Он просто передаёт значения своих параметров дальше.

Значения попадают в объект-обёртку errorObject. И если вторым параметром передана строка, errorObject отмечает, что ошибка предназначена для логирования.

Далее, ErrorHandler видя, что ошибка предназначена для логирования, перед запуском каждого уведомителя, проверяет игнорирует ли тот ошибки данного типа. Если - да, то пропускает этого уведомителя.

По умолчанию такие ошибки игнорирует только уведомитель ServerErrorNotifier, который запускается в production режиме. В его задачи входит отправка HTTP заголовка с кодом 500, показ страницы ошибки пользователю и остановка выполнения скрипта. Все остальные уведомители обработают эту ошибку.

Вот и получается, что в development режиме такая ошибка отобразится в браузере и разработчик сразу увидит её, а в production - попадёт только в лог. Потому, что для production режима в конфигурации заданы только два уведомителя: ServerErrorNotifier и FileNotifier.
Первый будет проигнорирован, а второй отработает.

Данное поведение обусловлено настройками конфигурации и, при желании, может быть изменено вплоть до диаметрально противоположного.


Callbak в shutdown_function

ErrorHandler предоставляет возможность выполнения пользовательских функций обратного вызова в ErrorHandler::shutdown(), которая зарегистрирована при помощи register_shutdown_function, и выполняется каждый раз при завершении работы скрипта.

Для чего это сделано?

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

Но есть некоторая особенность: пользовательские обработчики ошибок и исключений, зарегистрированные в скрипте не будут работать внутри таких функций.

Соответственно ErrorHandler не сможет обработать ошибки в shutdown_function зарегистрированной пользователем. Поэтому вам не стоит регистрировать ещё одну shutdown_function, а можно просто добавить сallbak, воспользовавшись методом:

Peraleks\ErrorHandler\Core\ErrorHandler::instance()->addUserCallback(callable $callback)

Внутри вашей сallbak ошибки будут обработаны.

Так как сallbak выполняется внутри shutdown_function, фатальные ошибки и E_COMPILE_WARNING не могут быть обработаны.

Clone this wiki locally