我有一个问题,我想要捕获所有异常,除了我的自定义异常的后代。
也许是糟糕的设计,但这里是(简化和名称更改,但代码非常准确):
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:有些不好。
我该怎么做?
答案 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异常,但也许这只是翻译/清理代码时的一些奇怪。