Nic*_*rns 2 language-agnostic exception-handling
我继承了一个代码库,其中包含如下代码(注意:示例代码是PHP):
try {
// Do something which doesn't intentionally throw exceptions.
} catch (\Exception $e) {
$this->log->log($e->getMessage());
$this->product->setError($e->getMessage());
return false;
}
Run Code Online (Sandbox Code Playgroud)
基本上,代码正在捕获异常.记录它,以及静默失败(除了日志消息).
这种行为似乎在生产中有意义,但使开发变得更加困难(因为必须在日志文件中查找堆栈跟踪,而不是将其打印到控制台).所以我想出了以下功能:
private function tryCatch ($func) {
// Bind closure, so that $this allows it to access class properties
if (is_object($func) && ($func instanceof Closure)) {
\Closure::bind($func, $this, "static");
}
if (\App::environment('test')) {
return $func();
} else {
try {
return $func();
} catch (\Exception $e) {
$this->log->log($e->getMessage());
$this->product->setError($e->getMessage());
return false;
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后可以像这样使用:
$this->tryCatch(function () {
// Do something
});
Run Code Online (Sandbox Code Playgroud)
这段代码特殊地描述了它在没有异常处理的情况下调用函数传递的'test'环境(因此任何异常都保持未处理状态).在每个其他环境(例如生产)中,它将传入的闭包在生产中的try-catch块中包装,就像代码最初的行为一样.
这个解决方案解决了我的问题,但它看起来有点hacky,让我感到有点唠叨,觉得这不是一个好主意.
我的问题:我有什么理由不这样做吗?或者有更好的方法来处理这种情况吗?
关于异常,不要试图重新发明轮子.只有一种情况,您应该catch
例外:
如果您有替代计划如何处理它,请抓住例外.
一个例外意味着您的代码遇到了一个特殊情况,它无法继续工作,别无选择,只能放弃.这是放弃函数/模块/执行上下文并向调用者发出更高信号的完美好方法.这正是例外所做的.
在开发过程中,您希望能够在其所有丑陋的荣耀中看到异常,以便能够进行调试.在生产中,您不希望您的用户看到异常,而是向他们展示一个漂亮的错误屏幕和/或有各种各样的铃声和口哨声,这通知管理员/开发人员/ CTO /谁.
这意味着,在生产中,您只需要一个全局错误处理程序,如果发生意外的未捕获异常,它将作出相应的响应.应该抛出异常并且(不)在开发中完全捕获,您不需要两个完全独立的代码路径.这个全局错误处理程序可以通过一些引导脚本有条件地设置set_exception_handler
; 或者甚至更好,您可以适当地配置您的Web服务器以提供有用的错误页面.配置Web服务器是最好的方法,因为这是一个特定于系统的设置(仅限生产),无需更改任何有关代码的内容.
实际编写a的唯一时间try..catch
是,如果子系统可能出现故障并且您有备份计划的合理原因.例如:
try {
$file = download_file_from_url($url);
echo "Cool, got your file.";
} catch (HttpNotFound $e) {
echo "Hey user, that file doesn't exist.";
} catch (HttpEmptyResponse $e) {
echo "Hey user, that file seems empty.";
}
..
Run Code Online (Sandbox Code Playgroud)
在这种情况下,失败的HTTP下载是预期的结果,并且可以很好地处理异常,因此这是一个很好的用例.但即使它们不代表预期的结果,也不要反思性地试图抓住它们.
归档时间: |
|
查看次数: |
1071 次 |
最近记录: |