为什么优秀的程序员有时会默默地吞下异常?

JiB*_*evé 37 language-agnostic exception-handling swallowed-exceptions

我知道它是邪恶的,但我已经看到一个好程序员编写的代码中的吞没异常.所以我想知道这种不良做法是否至少有一个积极的意义.

换句话说,这很糟糕,但为什么优秀的程序员在极少数情况下会使用它呢?

try
{
    //Some code
}
catch(Exception){}
Run Code Online (Sandbox Code Playgroud)

Ste*_*dit 44

查看我自己的代码,我在我的日志代码中找到了一个位置,在没有写入文件并且无法写入事件日志之后,它会吞下错误,因为没有地方可以报告它.这是一个例子:其他人并不多.

  • +1最糟糕的情况 - 喜欢它.类似于"创建错误报告时出错",除了......更糟糕?可能最好至少给用户一个警告.未能生成文件,未能生成错误报告,然后没有警告用户似乎是客户支持的噩梦'〜'. (7认同)
  • @Shadow:那将是一个非常不安全的假设.相反,我认为我是一个适度称职的程序员,其错误很快就会被优秀的程序员注意到并纠正. (6认同)
  • 你假设你是一个优秀的程序员:) (4认同)
  • 是的,如果只是不是Windows服务,我肯定会考虑显示一些内容.可以说,有些情况下,如果你无法登录,你应该立即杀死该应用程序.然而,这不是一个这样的情况. (2认同)

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只需要捕获已检查的异常.稍微重申了我的陈述.

  • (并假设它不是一个复杂的数字.) (3认同)

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检查要创建的对象类型的中,因此可以安全地吞下该异常.

  • 在JS代码中,为什么不删除try/catch? (3认同)

Jay*_*Jay 9

我只能想到我吞下异常的两种情况.

  1. 关闭文件或数据库连接时.如果我在结束时收到错误,我该怎么办呢?我想我真的应该写出某种错误信息,但如果我已经成功读取了数据,那似乎是多余的.它似乎也是一个非常不同的事件.

  2. 更合理:内部错误处理.如果我尝试写入日志文件失败,我将在哪里写出错误,说我无法写错误?在某些情况下,您可以尝试写入屏幕,但根据应用程序,这可能是不可能的,例如没有屏幕的后台作业; 或者只是让那些无法对错误做任何事情的用户感到困惑.

另一张海报提到了你知道异常是不可能的情况,或者至少,它会发生,你的编译器或操作环境会出现重大问题,比如它没有正确地将两个数字加在一起,在这种情况下谁说这个例外有意义吗?

我衷心同意,在这些合法的极少数情况下,你应该加上一条评论来解释为什么例外是不相关或不可能的.但是,我会说,无论何时编写可能含糊不清的代码,都应该包含解释性注释.

旁注:为什么程序员通常会包含诸如"x = x + 1; //将1添加到x"之类的注释,就像duh一样,我从来没有在没有注释的情况下将其配置出来,但是然后抛出非常神秘的代码而没有说明?

我原帖后四年的附录

当然,即使优秀的程序员有时会吞下异常的真正原因是:"我正在尝试使基本逻辑工作,我不知道如果发生这种异常该怎么办,我现在不想搞砸它我对正常的逻辑流程有太多的麻烦,但我稍后会再回过头来看." 然后他们忘了回到它.

顺便说一下,我听到几个人通常认为是非常好的程序员的一个坏理由是:"我不想向用户显示一个神秘的错误信息.这会让他们感到困惑.最好是默默地吞下错误. " 这是一个不好的原因,因为,(a)你仍然可以写一些日志文件.并且(b)一个神秘的错误信息是否真的比让用户产生操作成功的印象更糟糕?现在,顾客认为他们的订单正在处理,但实际上并没有,或者他们认为救护车正在派遣,以帮助他们的孩子在痛苦中尖叫但实际上消息从未经历过,等等.即使在最微不足道的情况下,论坛上的一个平淡的帖子没有发生或某些这样的,

  • 最后一段为+1.令我惊讶的是,有多少程序员 - 甚至是聪明的程序员 - 都无法理解这么明显的事情. (3认同)

Jus*_*ner 7

因为有时即使是优秀的程序员也会犯错误.

对于一个好的程序员而言你或者你对一些程序员的看法是不一样的(因为一个优秀的程序员会留下一些推理,说明为什么吞下Exception而不是用信息完成的事情).

  • 有时推理只是"我不关心异常". (3认同)

her*_*ter 6

因为必须为演示完成一些事情,所以老板明天会自然地做,并且没有什么比程序崩溃或显示令人讨厌的错误消息更糟糕,而当某些东西不能正常工作时,他总是可以"谈论".

演示结束后,没有人会改进那些"快速固定"的部分.;-)


Mik*_*ney 5

是的,我经常在异常清理代码中使用它们,这样我就不会掩盖原始异常.

例如,如果你的catch处理程序试图回滚事务并在重新启动异常之前关闭连接,则可能有几个原因导致回滚/关闭本身可能会失败(因为你已经因为原始例外).所以,可能希望用一个空的catch处理程序将clean包装在一个try块中,基本上说"如果清理中出现问题,那就太好了,因为我们有更大的问题需要报告"

  • 您可能想要记录清理失败。 (2认同)

Sar*_*tha 5

我相信这是因为Java的检查异常.我个人因为这个而讨厌他们,因为人们往往认为他们需要在任何地方使用异常处理代码.IMO在99%的代码中你应该把你的异常抛到堆栈而不处理它.如果创建的任何新方法的默认签名都在其中"抛出异常",我会很高兴,除非我愿意,否则我不必处理异常.

IMO您只需要在两个地方进行异常处理:1.用于资源清理,例如关闭输入流,数据库连接或删除文件.2.在堆栈的最顶层,您可以捕获异常并将其记录或显示给用户.

有些地方你真的不需要在catch中做任何事情,比如从Thread.sleep()处理InterruptedException,你至少应该有一个注释来说明你真的不希望发生任何事情那里.