Language agnostic 为什么优秀的程序员有时会默默地接受异常?
我知道这是邪恶的,但我也看到过优秀程序员编写的代码中存在异常。所以我想知道这个坏习惯是否至少有一个积极的方面 换句话说,它是不好的,但是为什么优秀的程序员在罕见的场合使用它呢Language agnostic 为什么优秀的程序员有时会默默地接受异常?,language-agnostic,exception-handling,swallowed-exceptions,Language Agnostic,Exception Handling,Swallowed Exceptions,我知道这是邪恶的,但我也看到过优秀程序员编写的代码中存在异常。所以我想知道这个坏习惯是否至少有一个积极的方面 换句话说,它是不好的,但是为什么优秀的程序员在罕见的场合使用它呢 try { //Some code } catch(Exception){} 因为有时候即使是优秀的程序员也会犯错误 或者你对一个好程序员的看法与其他人不一样(因为一个好的程序员会留下一些关于异常为何会被吞没的推理,而不是对信息进行处理的推理)。查看我自己的代码,我在我的日志代码中找到一个地方,在无法写入文件和无
try
{
//Some code
}
catch(Exception){}
因为有时候即使是优秀的程序员也会犯错误
或者你对一个好程序员的看法与其他人不一样(因为一个好的程序员会留下一些关于异常为何会被吞没的推理,而不是对信息进行处理的推理)。查看我自己的代码,我在我的日志代码中找到一个地方,在无法写入文件和无法写入事件日志之后,它会接受错误,因为没有地方可以报告它。这是一个例子:其他的例子并不多 可能是因为它不会被捕获,但无论如何都需要能够捕获。不过,我想不出任何理由来避免某种处理程序。我认为一个好的程序员在没有解释的情况下是不会这样做的
try
{
//Some code
}
catch(Exception e) {
// Explanation of why the exception is being swallowed.
}
不管出于什么原因,我都不太可能默默地吞下基本的异常类。我至少要把错误记录下来
下面是我今天在项目中偶然遇到的一个具体例子。这是获取浏览器支持的XMLHttpRequest
的JavaScript函数的一部分
var XMLHttp = null;
if( window.XMLHttpRequest ) {
try {
XMLHttp = new XMLHttpRequest();
} catch(e) {} // we've already checked that this is safe.
}
else if( window.ActiveXObject ) {
...
}
由于try
被包装在检查要创建的对象类型的if…else if
中,所以可以安全地吞下异常。是的,我经常在异常清理代码中使用它们,这样我就不会屏蔽原始异常
例如,如果您的catch处理程序试图回滚事务并在重新显示异常之前关闭连接,那么回滚/关闭本身可能会失败的原因有很多(因为原始异常已经导致您处于某种崩溃状态)。因此,可能想用一个空的catch处理程序将clean包装在一个try块中,基本上说“如果在清理过程中出现了问题,那没什么,因为我们有更大的问题要报告”我在无法有效处理异常时会这样做,它不应该影响应用程序的正常操作,和/或它可能代表已知但总体影响不大的瞬态条件
一个简单的例子是日志记录。你不需要因为某些日志信息不会保存到你的备份存储中而让应用程序崩溃
另一个例子可能是,您有其他方法来处理这些情况,例如:
private Boolean SomeMethod() {
Boolean isSuccessful = false;
try {
// call API function that throws one of several exceptions on failure.
isSuccessful = true;
} catch(Exception) { }
return isSuccessful;
}
在上面的示例中,您可能没有后备位置,但不希望它被过滤掉。对于返回值仅设置为成功状态(作为try块中的最后一步)的短方法,这是正常的
不幸的是,有许多调用会抛出异常,而不是简单地在结果中返回错误代码或false条件。我也看到过一些调用抛出的异常比他们的文档所建议的要多,这也是为什么我要在它们周围放一个陷阱的原因之一。即使只是因为无法对其进行任何处理,但有评论仍然很好。然而,在拥有稳定团队的定制/垂直应用程序中,如果原因在前面的代码中显而易见,那么这些细节有时就会消失。在不自称是一名优秀程序员的情况下,我至少可以解释为什么我有时会捕捉并忽略这些细节。有时,我正在处理的内容必须处理异常以进行编译,但这不是实际处理异常的适当位置。例如,我最近在一个程序中工作,该程序将解析大量XML作为其任务之一。实际的XML解析器打开了一个文件,该文件生成了一个异常。但是,XML解析器不是生成对话框的最佳位置,该对话框会通知用户错误的文件选择。我没有将异常抛出到正确的位置并在那里进行处理,而是默默地捕获了异常,留下了一条注释和待办事项(IDE为我跟踪)。这使我能够编译和测试,而无需实际处理异常。有时,我会忘记立即处理待办事项,而被吞下的异常会停留一段时间
我知道这不是最好的编程实践,我当然不是一个专业的程序员,但我认为这就是为什么有人想这样做的一个例子。因为有时程序员比编译器拥有更多的知识
例如(在某些虚构的语言中,被零除被视为错误):
由于某些语言(如Java)需要捕获某些/许多/所有异常,编译器可能会抱怨,而程序员知道这是不可能的。有时,让编译器关闭的唯一方法是明确地吞下异常
在编译器不抱怨的语言中,通常根本不编写空捕获
编辑:实际上,我会在catch块中添加一个断言(false)。如果理论上某件事不可能发生,那么当它在实践中确实发生时,这是一个非常严重的问题;)
Edit2:Java只需要捕获已检查的异常。重新编写了我的语句。至少要将其写入输出窗口
try
{ }
catch (exception ex)
{
System.Diagnostics.Debug.Writeline(" exception in method so and so : " ex.message);
}
我需要这样做一次,因为一个旧的框架在极少数情况下抛出了无意义的异常,而我并不关心。我只需要在有效的情况下运行它。我已经这样做了,当一些代码出现故障时,我希望程序继续运行。例如,我打开了一个可选的日志文件,无论它为什么无法工作,我都希望继续执行程序
尽管如此,这并不是好代码,因为您可能会遇到一些异常,比如内存不足异常,忽略这些异常毫无意义。因此,即使我已经这样做了,它仍然不是最好的
try
{ }
catch (exception ex)
{
System.Diagnostics.Debug.Writeline(" exception in method so and so : " ex.message);
}
Try
MyControl.BeginInvoke(MyControlUpdateDelegate);
Catch Ex as Exception
End Try