多个try-catch还是一个try-catch?

108

通常我会这样做:

try
{
    code

    code that might throw an anticipated exception you want to handle

    code

    code that might throw an anticipated exception you want to handle

    code
}
catch 
{

}

这种方式有什么好处吗?

code

try
{
    code that might throw an anticipated exception you want to handle
}
catch
{
}

code

try
{
    code that might throw an anticipated exception you want to handle
}
catch
{
}

code

更新:

我最初在与C#有关的情况下提出了这个问题,但正如A.Levy所评论的那样,它可以适用于任何异常处理语言,因此我更改了标签以反映这一点。


11
你希望在第一个错误发生时停止处理(第一个例子),还是即使处理的一部分失败也可以继续进行(另一个例子)? - David Pratte
3
@DLP - 我希望它停止处理 - 我看到有人在你之后提到了这一点。那是一个很好的观点。 - Steve
5
虽然您标记了C#和.NET,但我认为它实际上是与语言无关的。这个问题适用于任何带有异常处理机制的语言,如Java、C++、JavaScript、OCaml、F#、Python、Clojure等,也适用于Common Lisp和其他各种Lisp中的条件/重启系统。因此,我建议您将其翻译成与语言无关的问题……当然,最终决定由您作出。 - A. Levy
11个回答

127

这要看情况。如果您想为特定的错误提供特殊处理,则使用多个catch块:

try
{ 
    // code that throws an exception
    // this line won't execute
}
catch (StackOverflowException ex)
{
    // special handling for StackOverflowException 
}
catch (Exception ex)
{
   // all others
}

但如果意图是处理异常并继续执行,则将代码放置在单独的try-catch块中:

try
{ 
    // code that throws an exception

}
catch (Exception ex)
{
   // handle
}

try
{ 
    // this code will execute unless the previous catch block 
    // throws an exception (re-throw or new exception) 
}
catch (Exception ex)
{
   // handle
}

7
在第一个例子中,将+1标记出来,并确保通用异常处理程序在声明中排在最后,以便您首先处理特定异常,然后以通用方式处理超出您控制范围的任何其他异常。 - leeroya
如此声明:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch,条件捕获的使用是非标准的,也不在标准轨道上。不要在面向Web的生产站点上使用它:它不会为每个用户工作。实现之间可能存在较大的不兼容性,并且行为可能会在未来发生变化。 - JLavoie

24

如果我可以选择第二个选项,我可能会将其分成两个函数。


6
完全同意,不过我可能会这样写,“如果可以选择第二个选项,我会……”,因为我认为只要有可能,这是正确的做法。 - Reed Copsey

11

不需要使用解释,而是为特定异常使用多个catch块(除非该块中有大量代码,只有几行可能会抛出异常。在这种情况下,我会选择第二种方法)。


11
你的思路有误。在catch块中,你需要做什么?如果你可以通过运行相同的代码从任何可能的异常中恢复,无论哪个操作引发了异常,那么请使用一个catch块。如果你需要根据抛出异常的不同操作进行不同的清理操作,则使用多个catch块。
另外,如果你可以使用try/finally或RAII模式而不是try/catch,则应该这样做。

5

在我看来,第二种方法更好,因为它可以更准确地捕获错误。

而且,如果您将整个代码都包装在一个try/catch块中,那是不好的,因为如果您的应用程序出现问题并崩溃,由于您陷入了一个大型通用异常,您实际上能够正确处理它的机会就更小了。 你应该在try catch中有特定部分,比如如果你正在读取文件或接收用户输入。这样,您可以更好地处理异常。


3
有时我们希望向用户显示特定的错误信息。
try{
   try{
      ... send message
   }
   catch(exception e){
    ...log error
    ...rethrow  send related error/show custom error
   }
   try{
       ...try to receive response
   }
   catch(exception e){
       ...show receive related error
   }
   //finally close the connection
   }finally{
        ...close connection
   }

2

我更喜欢第二种方法 - 它使得调试更容易,错误处理更准确,而且还可以很好地衔接到单元测试中。


2

我会选择第二个选项,但每当我看到这种代码模式时,我的第一感觉就是考虑将其拆分成多个函数/方法。显然,是否要这样做取决于代码正在执行的任务 ;)


2

这取决于您的代码中发生错误的类型。

  1. 如果您要处理的这些错误的处理方式相同,请使用单个try ... catch来处理该组代码。否则,这将会非常繁琐。

  2. 如果需要不同的处理错误,请将其分开处理。

不要为所有情况应用单一方法。编程大多数时候是上下文特定的 :)

您需要在“好/复杂”和“坏/简单”之间达到平衡。您编写的代码越多,就会越少陷入这种困境 :)

祝您编程愉快!


2
通常来说,全文使用大写字母书写是不规范的。但最终,这取决于上下文。 - Joe Phillips

1

第二种方法。将可能引发异常的代码与其他代码分开 - 这样可以使该部分更小,更易于管理,而不是包装所有代码,即使不会引发异常的代码也要包装。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接