PHP: throw new Exception после Fatal Error

265
13 октября 2017, 16:47

Пишу свой класс-обработчик ошибок, в конструкторе реализую следующие обработчики:

    set_error_handler([$this, 'errorHandler']);
    set_exception_handler([$this, 'exceptionHandler']);
    ob_start();
    register_shutdown_function([$this, 'fatalErrorHandler']);

В каждом из этих методов я кидаю новое исключение, например:

public function fatalErrorHandler()
{
    $error = error_get_last();
    if ( !empty($error) && $this->isFatalError($error['type']) ) {
        ob_get_clean();
        throw new ErrorException($error['message'], $error['type']);
    } else {
        ob_end_flush();
    }
}

Класс ErrorException является внуком базового \Exception:

class ErrorException extends Exception
{
    const RESPONSE_CODE = 500;
}
class Exception extends \Exception { /* +новые функции */ }

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

Fatal error: Uncaught lynx\core\handlers\ErrorException: Uncaught Error: Call to undefined method **Error::array()** in vendor\lynx\core\ErrorHandler.php:124 Stack trace: #0 [internal function]: lynx\core\ErrorHandler->exceptionHandler(Object(Error)) #1 {main} thrown in C:\OpenServer\domains\smart-as.dev\vendor\lynx\core\ErrorHandler.php on line 110

То есть в обработчик исключений приходит не выкинутый мной ErrorException, а объект Error. Понятно, что он тоже потомок Throwable, но почему он то приходит?

Если кидать исключение объекта глобального \Exception то аналогично - в exeptionHandler (код ниже) приходит тот же Error. Не могу понять в чем проблемо, чего-то не понимаю, а нагуглить не могу.

public function exceptionHandler(Exception $e)
{
    $this->error = $e->array();
    $this->displayError($e->getResponseCode());
    $this->logErrors();
}

Заранее спасибо!

Answer 1

Согласно документации:

set_exception_handler — Задает пользовательский обработчик исключений

Список параметров: $exception_handler

Имя функции, которая будет вызываться каждый раз, когда выбрасывается неперехватываемое исключение. Функция-обработчик должна принимать один аргумент - объект, представляющий выброшенное исключение. До PHP 7 такая функция выглядит так:

void handler ( Exception $ex )

В PHP 7 большинство внутренних ошибок теперь генерируют исключение, но класса Error. Для них так же будет вызываться указанный обработчик исключений. Классы Error и Exception реализуют интерфейс Throwable, соответственно именно его следует использовать в сигнатуре функции-обработчика:

void handler ( Throwable $ex )

Предостережение
Указание типа Exception для параметра ex в вашей функции-обработчике приведет к проблемам в PHP 7 из-за измененной иерархии классов исключений.

в общем в вашем случае, все, как написано в доках, один в один.

Answer 2

Из документации:

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

Соответственно в моей ситуации в принципе срабатывал сначала exceptionHandler, в который приходил объект Error. А я же думал, что это пораждается fatalErrorHandler'ом.

READ ALSO
Как спрятать ряды таблицы?

Как спрятать ряды таблицы?

Добрый день профессионалыКак спрятать таблицу, кликая по "шапке таблицы"? Сейчас я это делаю через Javascript, а в тэг ряда таблицы вставляю

212
Сохранить mp3 файл с помощью php

Сохранить mp3 файл с помощью php

Есть ссылка нужно скачать и сохранить файл, не подскажите как? Сначала курл, а потом fwrite?

187
Не работает сайт на веб сервере

Не работает сайт на веб сервере

Здравствуйте! Есть сайт, который нормально работает на локальным сервереКогда заливаю на веб сервер, вылезает куча ошибок

168
Выбор определенной ячейки SQL

Выбор определенной ячейки SQL

ЗдравствуйтеИдея такова- есть таблица MySQL, допустим, с 2мя столбцами

200