JiB*_*evé 37 language-agnostic exception-handling swallowed-exceptions
我知道它是邪恶的,但我已经看到一个好程序员编写的代码中的吞没异常.所以我想知道这种不良做法是否至少有一个积极的意义.
换句话说,这很糟糕,但为什么优秀的程序员在极少数情况下会使用它呢?
try
{
//Some code
}
catch(Exception){}
Run Code Online (Sandbox Code Playgroud)
Ste*_*dit 44
查看我自己的代码,我在我的日志代码中找到了一个位置,在没有写入文件并且无法写入事件日志之后,它会吞下错误,因为没有地方可以报告它.这是一个例子:其他人并不多.
Sjo*_*erd 24
因为有时程序员比编译器有更多的知识.
例如(在一些虚构的语言中,除以零被视为错误):
try {
x = 1 / (a*a + 1);
} catch (DivisionByZeroException ex) {
// Cannot happen as a*a+1 is always positive
}
Run Code Online (Sandbox Code Playgroud)
由于某些语言(例如Java)需要捕获一些/多个/所有异常,编译器可能会抱怨,而程序员知道它是不可能的.有时让编译器关闭的唯一方法是明确地吞下异常.
在编译器不抱怨的语言中,通常根本不写入空捕获.
编辑:在实践中,我会在catch块中添加一个断言(false).如果理论上某些事情不可能发生,那么当它在实践中确实发生时,这是一个非常严重的问题;)
Edit2:Java只需要捕获已检查的异常.稍微重申了我的陈述.
Bil*_*ard 15
我认为一个优秀的程序员如果不解释它就不会这样做.
try
{
//Some code
}
catch(Exception e) {
// Explanation of why the exception is being swallowed.
}
Run Code Online (Sandbox Code Playgroud)
Exception无论出于何种原因,我都不太可能只是默默地吞下基类.我至少会尝试记录错误.
这是我刚刚在我的项目中遇到的一个具体例子.这是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 ) {
...
}
Run Code Online (Sandbox Code Playgroud)
由于try包含在一个if...else if检查要创建的对象类型的中,因此可以安全地吞下该异常.
我只能想到我吞下异常的两种情况.
关闭文件或数据库连接时.如果我在结束时收到错误,我该怎么办呢?我想我真的应该写出某种错误信息,但如果我已经成功读取了数据,那似乎是多余的.它似乎也是一个非常不同的事件.
更合理:内部错误处理.如果我尝试写入日志文件失败,我将在哪里写出错误,说我无法写错误?在某些情况下,您可以尝试写入屏幕,但根据应用程序,这可能是不可能的,例如没有屏幕的后台作业; 或者只是让那些无法对错误做任何事情的用户感到困惑.
另一张海报提到了你知道异常是不可能的情况,或者至少,它会发生,你的编译器或操作环境会出现重大问题,比如它没有正确地将两个数字加在一起,在这种情况下谁说这个例外有意义吗?
我衷心同意,在这些合法的极少数情况下,你应该加上一条评论来解释为什么例外是不相关或不可能的.但是,我会说,无论何时编写可能含糊不清的代码,都应该包含解释性注释.
旁注:为什么程序员通常会包含诸如"x = x + 1; //将1添加到x"之类的注释,就像duh一样,我从来没有在没有注释的情况下将其配置出来,但是然后抛出非常神秘的代码而没有说明?
我原帖后四年的附录
当然,即使优秀的程序员有时会吞下异常的真正原因是:"我正在尝试使基本逻辑工作,我不知道如果发生这种异常该怎么办,我现在不想搞砸它我对正常的逻辑流程有太多的麻烦,但我稍后会再回过头来看." 然后他们忘了回到它.
顺便说一下,我听到几个人通常认为是非常好的程序员的一个坏理由是:"我不想向用户显示一个神秘的错误信息.这会让他们感到困惑.最好是默默地吞下错误. " 这是一个不好的原因,因为,(a)你仍然可以写一些日志文件.并且(b)一个神秘的错误信息是否真的比让用户产生操作成功的印象更糟糕?现在,顾客认为他们的订单正在处理,但实际上并没有,或者他们认为救护车正在派遣,以帮助他们的孩子在痛苦中尖叫但实际上消息从未经历过,等等.即使在最微不足道的情况下,论坛上的一个平淡的帖子没有发生或某些这样的,
因为有时即使是优秀的程序员也会犯错误.
对于一个好的程序员而言你或者你对一些程序员的看法是不一样的(因为一个优秀的程序员会留下一些推理,说明为什么吞下Exception而不是用信息完成的事情).
因为必须为演示完成一些事情,所以老板明天会自然地做,并且没有什么比程序崩溃或显示令人讨厌的错误消息更糟糕,而当某些东西不能正常工作时,他总是可以"谈论".
演示结束后,没有人会改进那些"快速固定"的部分.;-)
是的,我经常在异常清理代码中使用它们,这样我就不会掩盖原始异常.
例如,如果你的catch处理程序试图回滚事务并在重新启动异常之前关闭连接,则可能有几个原因导致回滚/关闭本身可能会失败(因为你已经因为原始例外).所以,可能希望用一个空的catch处理程序将clean包装在一个try块中,基本上说"如果清理中出现问题,那就太好了,因为我们有更大的问题需要报告"
我相信这是因为Java的检查异常.我个人因为这个而讨厌他们,因为人们往往认为他们需要在任何地方使用异常处理代码.IMO在99%的代码中你应该把你的异常抛到堆栈而不处理它.如果创建的任何新方法的默认签名都在其中"抛出异常",我会很高兴,除非我愿意,否则我不必处理异常.
IMO您只需要在两个地方进行异常处理:1.用于资源清理,例如关闭输入流,数据库连接或删除文件.2.在堆栈的最顶层,您可以捕获异常并将其记录或显示给用户.
有些地方你真的不需要在catch中做任何事情,比如从Thread.sleep()处理InterruptedException,你至少应该有一个注释来说明你真的不希望发生任何事情那里.