Преобразование ошибок в исключения: ошибка проектирования?

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

class AppException extends Exception
{

}

function error_handler($errno, $errstr, $errfile, $errline)
{
    throw new AppException($errstr, $errno);
}

function exception_handler($exception)
{
    $min = ...;
    $max = ...;

    if ($exception->getCode() >= $min && $exception->getCode() <= $max)
    {
        // log exception
    }
}

set_error_handler('error_handler');
set_exception_handler('exception_handler');

$a[1]; // throws exception

Проблема в том, что я видел такие вещи, как:

try
{
    do_something();
}
catch (AppException $exception)
{
}

Что подразумевает отсутствие различий между фактическими ошибками программирования и «исключительным» поведением. После дальнейшего изучения я наткнулся на части кода, которые были разработаны вокруг идеи, что ошибки PHP представляют собой «исключительное» поведение, такое как:

...

function my_function($param1, $param2)
{
    // do something great
}

try
{
    my_function('only_one_param');
}
catch (AppException $exception)
{
}

Что в итоге запутывает ошибки и дизайн интерфейса приложения.

Что вы думаете об обработке ошибок таким образом? Стоит ли превращать нативные ошибки PHP в исключения? Что вы делаете в ситуациях, подобных описанным выше, когда кодовая база разработана вокруг этой идеи?

10
задан rr. 21 August 2014 в 17:29
поделиться

2 ответа

Лично я делаю это постоянно. Единственное отличие состоит в том, что в моей функции error_handler я сначала проверяю, является ли ошибка E_NOTICE , и бросаю только в том случае, если это не так (я все равно регистрирую уведомление). .

Я бы изменил AppException на что-то, что расширяет ErrorException ... Примерно так: PhpRuntimeErrorException расширяет ErrorException , который вы ТОЛЬКО используете для ошибок PHP .. Причина в том, что оно более читабельно (легче определить, что такое PhpRuntimeErrorException , без необходимости выяснять, где оно возникло). Другая причина заключается в том, что ErrorException будет хранить информацию о генерирующей строке / файле / и т.д., где она не будет храниться где-либо еще (поскольку обратная трассировка начинается со строки throw ). .

Итак, вы можете «попробовать» такой код:

try {
    $f = fopen('foo.bar', 'r');
    $ret = '';
    while ($data = fread($f)) {
        $ret .= process($data);
    }
    fclose($f);
    return '';
} catch (PHPRuntimeErrorException $e) {
    throw new RuntimeException('Could not open file');
} catch (ProcessException $e) {
    fclose($f);
    throw new RuntimeException('Could not process data');
}
return $ret;

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

Просто мой опыт и мнение ...

16
ответ дан 3 December 2019 в 17:56
поделиться

В сообществе PHP были некоторые дебаты по этому поводу. Я полагаю, что общее мнение таково, что ошибки - это то, что выбрасывается внутренними функциями PHP, и это проблемы кодирования, которые вам действительно нужно исправить; в то время как исключения - это то, что выбрасывается кодом вашего приложения, который вам, возможно, нужно просто "обработать".

Однако некоторые из новых расширений SPL (более объектно-ориентированные) используют исключения для вещей, которые раньше могли бы вызывать ошибки, так что здесь есть некоторая серая зона.

Существует также класс ErrorException ядра PHP - http://www.php.net/manual/en/class.errorexception.php, который выглядит немного проще в использовании, чем ваш пример кода, если вы хотите пойти по этому пути.

5
ответ дан 3 December 2019 в 17:56
поделиться
Другие вопросы по тегам:

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