Преобразование ошибок в исключения: недостаток дизайна? - PullRequest
10 голосов
/ 06 августа 2010

Недавно я наткнулся на некоторый код, который использовал собственный обработчик ошибок, чтобы превратить любые ошибки 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 в исключения?Что вы делаете в ситуациях, подобных описанным выше, когда кодовая база разработана вокруг этой идеи?

Ответы [ 3 ]

16 голосов
/ 06 августа 2010

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

Я бы изменил AppException на что-то, что расширяет ErrorException ... Что-то вроде: PhpRuntimeErrorException extends 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 ошибок сервера. Это потому, что любые исключения должны быть перехвачены, и если это не так, это действительно ошибка сервера ...

Только мой опыт и мнение ...

5 голосов
/ 06 августа 2010

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

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

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

1 голос
/ 05 ноября 2013

Я конвертирую все, включая уведомления в исключения. Нет причин, чтобы исключения продолжались как обычно. Неопределенная переменная или смещение? Это проблема.

https://github.com/KyleWolfe/PHPErrorNet

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...