Php选择性异常处理

时间:2014-08-15 20:22:19

标签: php exception

我有一个问题,我想要捕获所有异常,除了我的自定义异常的后代。

也许是糟糕的设计,但这里是(简化和名称更改,但代码非常准确):

function doStuff()
{
    try {
        // code
        if (something) {
            // manually throw an exception
            throw StuffError("Something is bad.");
        }

        // a third-party code, can throw exceptions
        LibraryClass::arcaneMagic();

    } catch (Exception $e) {
        throw new StuffError("Error occured while doing stuff: "
             . $e->getMessage());
    }
}

/** My custom exception */
class StuffError extends Exception
{
    function __construct($msg) {
        parent::__construct('StuffError: ' . $msg);
    }
}

但是,这里的问题是我不希望try-catch拦截手动抛出StuffError。或者,无缝地重新抛出它或其他东西。

就像现在一样,我会得到:

  

StuffError:在做东西时发生错误:StuffError:有些东西不好。

我只想:

  

StuffError:有些不好。

我该怎么做?

2 个答案:

答案 0 :(得分:2)

您可以拥有多个catch子句,匹配的第一个子句将是运行的子句。所以你可以这样:

try {
    do_some_stuff();
}
catch (StuffError $e) {
    throw $e;
}
catch (Exception $e) {
    throw new StuffError(Error occurred while doing stuff: " . $e->getMessage());
}

但你可能想重新考虑包装这样的东西。它掩盖了错误的真正原因。首先,你丢失了堆栈跟踪。但它也使错误处理变得复杂,因为现在有人无法按照您尝试的方式区分异常类型,而不是尝试解析异常消息(这本身就是反模式)。

答案 1 :(得分:0)

我可能会误解你,但我认为这就是你要找的东西:

    ...

} catch (Exception $e) {
    if (get_class($e) == 'StuffError' || is_subclass_of($e, 'StuffError')) {
        throw $e;
    } else {
        throw new StuffError("Error occured while doing stuff: "
             . $e->getMessage());
    }
}

    ...

用上面的代码替换你的catch语句。它检查异常是StuffError还是StuffError的子类。我仍然非常困惑为什么你需要在捕获之后抛出一个StuffError异常,但也许这只是翻译/清理代码时的一些奇怪。

相关问题