为什么空捕获阻止了一个坏主意?

Sam*_*ijo 177 exception-handling try-catch

我刚刚看到一个关于try-catch问题,人们(包括Jon Skeet)说空的拦截块是一个非常糟糕的主意?为什么这个?没有空的捕获不是错误的设计决定的情况吗?

我的意思是,例如,有时你想从某个地方(网络服务,数据库)获得一些额外的信息,你真的不在乎你是否会收到这些信息.所以你试图得到它,如果有什么事情发生,那没关系,我只会添加一个"catch(Exception ignored){}",这就是全部

Ned*_*der 288

通常空的try-catch是一个坏主意,因为你正在静默地吞下错误条件然后继续执行.偶尔这可能是正确的事情,但通常这是一个迹象,开发人员看到一个例外,不知道该怎么做,所以使用空捕获来解决问题.

它的编程相当于将黑色胶带放在发动机警告灯上.

我相信你如何处理异常取决于你正在使用的软件层:雨林中的例外情况.

  • 也喜欢这个比喻 - 和所有规则一样,也有例外.例如,如果你从不打算做定时录音,那么在录像机上闪烁的时钟上使用黑色磁带是完全可以的(对于那些记得录像机是什么的老人来说). (36认同)
  • @Jason:至少,你应该包括一个详细的评论,解释你为什么要对异常进行沉默. (5认同)
  • 在那些真正罕见的情况下,我*真的*不需要异常*并且由于某些原因*日志不可用,我确保评论它是故意的 - 以及为什么不需要它,并重申我仍然更喜欢如果在该环境中可行则记录它.基本上我发表评论比在这种情况下可以选择的日志工作更多.幸运的是,我只有2个客户,这是一个问题,而且只有在从他们的网站发送非关键电子邮件时才会这样. (4认同)
  • 就像任何偏离公认的做法一样,如果合适的话,将其记录下来,以便下一个人知道你做了什么以及为什么做. (3认同)
  • 你概括了 try-catch 是个坏主意!实际上这是个好主意。想象一个没有用户交互的系统!?并且应该继续运行!。就我而言,我的系统应该始终 24/7 全天候工作。所以它不能熄灭。在某些情况下,我尝试写入文件,我不在乎它是否成功完成,我关心的是保持整个系统运行 (2认同)

Ada*_*son 35

总的来说,它们是一个坏主意,因为这是一种真正罕见的情况,其中失败(特殊条件,更一般地)正确地满足了无响应.最重要的是,空catch块是使用异常引擎进行错误检查的人们使用的常用工具,他们应该先发制人.

说它总是坏的是不真实的......这是非常的.在某些情况下,您可能不关心是否存在错误,或者错误的存在以某种方式表明您无法对其执行任何操作(例如,将以前的错误写入文本日志文件时你得到一个IOException,意味着你无论如何也无法写出新的错误).


lub*_*sko 10

我不会延伸到使用空挡块的人是一个糟糕的程序员并且不知道他在做什么......

如有必要,我会使用空的catch块.有时我正在消费的图书馆程序员不知道他在做什么,即使在没人需要的情况下也会抛出异常.

例如,考虑一些http服务器库,如果服务器抛出异常,我不在乎,因为客户端已断开连接而index.html无法发送.

  • 你当然过度概括了.仅仅因为*你*不需要它并不意味着没有人这样做.即使绝对没有什么可以做出回应,也有人需要收集有关废弃连接的统计数据.因此,假设"图书馆程序员不知道他在做什么"是相当粗鲁的. (5认同)

Dan*_*den 8

在极少数情况下可以证明其合理性.在Python中,您经常会看到这种结构:

try:
    result = foo()
except ValueError:
    result = None
Run Code Online (Sandbox Code Playgroud)

所以可能没问题(取决于你的应用程序):

result = bar()
if result == None:
    try:
        result = foo()
    except ValueError:
        pass # Python pass is equivalent to { } in curly-brace languages
 # Now result == None if bar() returned None *and* foo() failed
Run Code Online (Sandbox Code Playgroud)

在最近的.NET项目中,我不得不编写代码来枚举插件DLL以查找实现某个接口的类.相关的代码(在VB.NET中,抱歉)是:

    For Each dllFile As String In dllFiles
        Try
            ' Try to load the DLL as a .NET Assembly
            Dim dll As Assembly = Assembly.LoadFile(dllFile)
            ' Loop through the classes in the DLL
            For Each cls As Type In dll.GetExportedTypes()
                ' Does this class implement the interface?
                If interfaceType.IsAssignableFrom(cls) Then

                    ' ... more code here ...

                End If
            Next
        Catch ex As Exception
            ' Unable to load the Assembly or enumerate types -- just ignore
        End Try
    Next
Run Code Online (Sandbox Code Playgroud)

虽然在这种情况下,我承认在某处记录故障可能会有所改善.


Jus*_*tin 6

通常会放入空的挡块,因为编码器并不真正知道它们在做什么.在我的组织中,一个空的catch块必须包含一个注释,说明为什么对异常做任何事情都是个好主意.

在相关的说明中,大多数人不知道try {}块可以跟随catch {}或finally {},只需要一个.

  • 除非你当然在谈论IE6或IE7 ;-) ...其中catch*IS*需要或者最终不执行.(这在IE8 btw修复) (3认同)

Ree*_*sey 6

只有在存在真正异常的情况下才会抛出异常 - 超出常规的事情.一个空的挡块基本上说"发生了一些不好的事情,但我只是不在乎".这是一个坏主意.

如果您不想处理异常,请让它向上传播,直到它到达一些可以处理它的代码.如果没有任何东西可以处理异常,则应该关闭应用程序.

  • 有时你知道它不会影响任何事情.然后继续做,并评论它,以便下一个人不只是认为你搞砸了,因为你是无能的. (3认同)
  • @David Thornley:如果你不至少检查异常以确定它是一个预期的无意义的错误还是应该向上传播的错误,你怎么知道它不会影响任何事情? (2认同)
  • @Dave:虽然`catch(Exception){}`是个坏主意,`catch(SpecificExceptionType){}`可能完全没问题.程序员DID使用catch子句中的类型信息检查异常. (2认同)

bal*_*pha 6

我认为如果你捕获一个特殊的异常类型是可以的,你知道它只会因为一个特定的原因而被提出,并且你期望该异常并且真的不需要对它做任何事情.

但即使在这种情况下,调试消息也可能是有序的.


Kri*_*kar 5

乔希布洛赫 - 65项:不要忽视异常有效的Java:

  1. 一个空的捕获块会破坏异常的目的
  2. 至少,catch块应该包含一个注释,解释为什么忽略异常是合适的.