代码之家  ›  专栏  ›  技术社区  ›  rr.

将错误转换为异常:设计缺陷?

  •  10
  • rr.  · 技术社区  · 14 年前

    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)
    {
    }
    

    ...
    
    function my_function($param1, $param2)
    {
        // do something great
    }
    
    try
    {
        my_function('only_one_param');
    }
    catch (AppException $exception)
    {
    }
    

    最终导致混淆错误和应用程序接口的设计。

    3 回复  |  直到 10 年前
        1
  •  16
  •   ircmaxell    14 年前

    就我个人而言,我一直都这么做。唯一的区别是在我的 error_handler 函数,我检查错误是否为 E_NOTICE 首先,只有在没有的情况下才抛出(无论如何我都会记录通知)。。。

    AppException 延伸到某物 ErrorException PhpRuntimeErrorException extends ErrorException 只用于PHP错误。。。原因是这样的,它更可读(更容易判断什么是 PhpRuntimeErrorException 不需要弄清楚它被扔到哪里)。另一个原因是 将存储生成行/文件/etc信息,而不会存储在其他位置(因为回溯从 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;
    

    只是我的经验和观点。。。

        2
  •  5
  •   Tim Fountain    12 年前

    在PHP社区中对此有一些争论。我相信一般的想法是,错误是内部PHP函数抛出的东西,是您真正需要修复的编码问题;而异常是应用程序代码抛出的东西,您可能只需要“处理”。

    还有一个PHP核心类ErrorException- http://www.php.net/manual/en/class.errorexception.php 这看起来比你的代码示例更容易使用,如果这是你想走的路线的话。