我有一个问题,我想捕获所有异常,除了我的自定义异常的后代。
可能是糟糕的设计,但这里是(简化和名称更改,但代码相当准确):
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异常后,你捕获,但也许这只是一些奇怪的翻译/清理你的代码。