嵌套的“尝试/捕获”块是个坏主意吗?


81

假设我们有一个像这样的结构:

Try
  ' Outer try code, that can fail with more generic conditions, 
  ' that I know less about and might not be able to handle

  Try
    ' Inner try code, that can fail with more specific conditions,
    ' that I probably know more about, and are likely to handle appropriately
  Catch innerEx as Exception
    ' Handle the inner exception
  End Try

Catch outerEx as Exception
  ' Handle outer exception
End Try

我已经看到一些意见认为Try不鼓励使用这种嵌套块,但是我找不到任何具体原因。

这是错误的代码吗?如果是这样,为什么?


2
不确定代码段的准确度。但是,当您捕获到Exception时,您并没有真正了解的东西。可以是任何东西。考虑利用VB.NET支持的When子句。
汉斯·帕桑

Answers:


85

在某些情况下,它们是一个好主意,例如,对于整个方法,一个try / catch和一个循环中的另一个try / catch,因为您想处理异常并继续处理集合的其余部分。

真正做到这一点的唯一原因是,如果您想跳过出错的位并继续操作,而不是取消堆栈并丢失上下文。在编辑器中打开多个文件就是一个例子。

就是说,例外应该(如名称所示)是例外。程序应处理它们,但应尽量避免将它们作为正常执行流程的一部分。在大多数语言中,它们在计算上都很昂贵(Python是一个值得注意的例外)。

另一种有用的技术是捕获特定的异常类型...

Try
    'Some code to read from a file

Catch ex as IOException
    'Handle file access issues (possibly silently depending on usage)
Catch ex as Exception
    ' Handle all other exceptions.
    ' If you've got a handler further up, just omit this Catch and let the 
    ' exception propagate
    Throw
End Try

我们还在错误处理例程中使用嵌套的try / catches ...

    Try
        Dim Message = String.Format("...", )
        Try
            'Log to database
        Catch ex As Exception
            'Do nothing
        End Try

        Try
            'Log to file
        Catch ex As Exception
            'Do nothing
        End Try
    Catch ex As Exception
        'Give up and go home
    End Try

7
登录后台线程是我将使用内部try / catch的地方。我不希望方法结束,因为它无法记录它在做什么。
gooch

@Gooch是的,我也这样做,我将其添加到我的答案中。
基本

37

实际上,我认为嵌套Try/Catch块没有任何内在的错误,除了嵌套/块可能难以导航并且可能表明您可以进行一些重构(例如,将内部Try/Catch转换为自己的方法)。

但我确实想解决此评论:

' Outer try code, that can fail with more generic conditions, 
' that I know less about and might not be able to handle

如果您不知道如何在特定情况下处理异常,请相信我:不要抓住它们。最好让您的应用程序崩溃(我的意思是,将其记录下来;只是不要吞下它),而不是捕获某些您不知道如何从中恢复的东西,然后让您的应用程序在损坏状态下快乐地继续前进。从那时起,行为充其量是不可预测的。


那是真实的。在捕获外部异常时,我不想继续。我更多地是想能够正常关闭/重新启动应用程序,而不会因“丑陋的崩溃”而震惊用户
Goro

10
@Goro:在那种情况下,我建议使用应用程序范围的异常处理机制(例如,如果这是WinForms,则处理Application.UnhandledException事件),而不是按方法Try/Catch块。
丹涛
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.