Php选择性异常处理


Php selective exception handling

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

可能是糟糕的设计,但这里是(简化和名称更改,但代码相当准确):

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: Something is bad.

我只想:

StuffError: Something is bad.

我该怎么做?

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

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

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

我可能误解了你,但我认为这是你要找的:

    ...
} 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异常后,你捕获,但也许这只是一些奇怪的翻译/清理你的代码。