php - 如何最好地处理 catch 块中抛出的异常?
问题描述
假设我有一个 try/catch 块,如果发生不好的事情,我需要在 catch 块中进行一些清理。然后我想重新抛出原始异常让应用程序代码处理它。
例如,可以像这样回滚数据库事务:
try {
startTransaction();
doSomethingThatThrowsAnException();
} catch (Exception $e) {
rollbackTransaction();
throw $e;
}
很好,但是回滚可能会失败并抛出异常。然后我的应用程序将只看到回滚异常而不是原始异常。然后我会错过最有用的信息,这是不好的。
所以我可能会将代码更改为:
try {
startTransaction();
doSomethingThatThrowsAnException();
} catch (Exception $e) {
try {
rollbackTransaction();
} catch (Exception $ex) {
// Do nothing
}
throw $e;
}
这更好,但现在我不知道清理/回滚也失败了。也许回滚功能中有一个我永远找不到的错误。我想获得有关这两个例外的完整信息。
到目前为止,我想出的最好的方法是创建一个新异常,保留有关回滚异常的消息,并像以前一样发送原始异常:
try {
startTransaction();
doSomethingThatThrowsAnException();
} catch (Exception $e) {
try {
rollbackTransaction();
} catch (Exception $ex) {
throw new Exception($ex->getMessage(), $ex->getCode(), $e);
}
throw $e;
}
但这并不完美,我仍然丢失了一些关于回滚异常的信息,比如它的堆栈跟踪。
我还尝试创建另一个包含两个异常的异常类:
try {
startTransaction();
doSomethingThatThrowsAnException();
} catch (Exception $e) {
try {
rollbackTransaction();
} catch (Exception $ex) {
throw new MultiException($e, $ex);
}
throw $e;
}
class MultiException extends Exception
{
private $exceptions = [];
public function __construct(...$exceptions)
{
$this->exceptions = $exceptions;
}
public function __toString()
{
return implode("\n", $this->exceptions);
}
}
但我不确定这将如何与各种日志记录框架一起使用。例如,只能覆盖 __toString() 方法,而不能覆盖 getTrace()。
有没有更好的方法或一些最佳实践来处理这样的案例?
解决方案
推荐阅读
- java - 尝试编辑数据集时 eclipse 冻结并且没有响应
- c# - 数组 c# 中的子字符串 (Unity)
- nginx - proxy_pass 以 nginx 变量作为参数
- php - 加载资源失败:服务器响应状态为 408 (Request Timeout) safari 11.10
- php - 如何将日期时间字符串转换为当前时区
- sql - 我可以以某种方式将变量声明为查询结果吗?
- php - 聚合某些键的数组值
- javascript - DataTables FixedHeader 不随屏幕滚动
- php - 关于表格和PHP的两个简单问题
- android - 单击外部链接时如何在 WebView 应用程序中打开 Web 浏览器?