我想捕获一个自定义异常,对它执行一些逻辑,如果失败,则将其抛给更通用的catch块。像这样:
class My_Exception extends Exception {
protected $_nonFatal = false;
public function __construct($value, $nonFatal = false) {
$this->_nonFatal = (bool)$nonFatal;
return parent::__construct($value);
}
public function isNonFatal() {
return (bool)$this->_nonFatal;
}
}
try {
} catch (My_Exception $e) {
if ($e->isNonFatal) {
// #1
// Err gently
}
// #2
// The error was fatal, so keep throwing it
throw new Exception($e->getMessage());
} catch (Exception $e) {
// #3
echo 'An exception was caught with the message '.$e->getMessage();
}
所以我抓住My_Exception
,检查它是否是非致命错误。如果是这样,请轻轻地(第1节)。如果不是(第2节),我希望触发第二个捕获,(第3节。)相反,第2节中的throw new Exception
将try/catch/catch
全部放在一起。
我可以在$e
的类上使用switch语句,但我觉得这很麻烦。有没有一种标准的方法可以解决这个问题?
答案 0 :(得分:2)
如果不是(第2节),我希望触发第二次捕获
尝试/捕获块不会像那样工作 - 一个catch块总是会突破try / catch块;它没有"经过"比如switch语句可以。
您需要使用另一个try / catch块包装代码。
try {
try {
// ...
} catch (My_Exception $e) {
if ($e->isNonFatal) {
// #1
// Err gently
}
// #2
// The error was fatal, so keep throwing it
throw new Exception($e->getMessage());
}
} catch (Exception $e) {
// #3
echo 'An exception was caught with the message '.$e->getMessage();
}
有没有一种标准的方法可以解决这个问题?
没有真正的"标准"这样做的方式;通常你不会在另一个例外中概括一个例外,但如果申请是正确的,那么这就是你想要这样做的。
管理异常链的更好方法是在构造函数中pass your custom exception a the previous exception。这样,无论选择异常,都可以使用Exception.getPrevious()
,并在更通用的情况下显示您的例外情况。
答案 1 :(得分:1)
不幸的是,catch块无法处理在同级catch块之前抛出的任何异常,即使它是从另一个函数调用中抛出的。 换句话说,从块#{<1}}内部抛出的任何未处理的异常将不会从块#2 内部看到(但将由调用堆栈中的偶数上部catch块处理) :
#1
那么,坦率地说,立即嵌套的try / catch块看起来很难看 如果您的应用程序逻辑不是太复杂,您可以使用instanceof运算符保持代码整洁。
try {
error_prone_code();
} catch (My_Exception $e) { // #1
throw new \Exception($e->getMessage());
} catch (Exception $e) { // #2
echo "Something bad happend: {$e->getMessage()}";
}