异常处理:在catch块中使用try-catch

64

最近我遇到了一位同行写的代码,他在catch语句块中放了一个try-catch语句块!

请原谅我无法复制实际代码,但他做的类似于这样:

try
{
 //ABC Operation
}
catch (ArgumentException ae)
{
   try
   {
      //XYZ Operation
   }
   catch (IndexOutOfRangeException ioe)
   {
      //Something
   }
}

我个人认为这是我见过的最糟糕的代码之一!在1到10的评分中,你认为我应该多快去表达我的看法,还是我反应过度了?

编辑: 实际上他在catch块中执行了一些操作,这些操作可以/应该在初始try失败时完成。我的问题是代码清晰性和可维护性。将异常从第一个catch块委托给不同的函数或调用函数是可以接受的,但在第一个catch块中添加可能会或可能不会引发异常的更多代码,则是我感觉不好的地方。我尽量避免多重堆叠的“if循环”语句,我发现这同样糟糕。


24
这很常见,因此如果不看实际代码的操作,这并没有本质上的问题。 - nos
11
我宁愿问他想要达到什么目的。 - Martin York
3
最终在这里想知道这样的事情是否可能... :) - Hayden Thring
3个回答

209

为什么这样做不好?从概念上讲,它与以下代码没有任何区别:

void TrySomething() {
   try {


   } catch (ArgumentException) {
        HandleTrySomethingFailure();
   }
}

void HandleTrySomethingFailure() {
    try {

    } catch (IndexOutOfRangeException) {

    }
}
在你去那里,想要让他"体会一下"以及冒犯他(试试顶顶顶脑壳,这样效果最佳)之前,你确切地打算对他说什么呢?你将如何回答那句引经据典的“为什么?”?
更具讽刺意味的是,当抖动内联此代码时,它看起来会和你的示例完全相同。
-Oisin

25
我完全同意。如果你觉得他的代码有问题,并且愿意面对他提出质疑,那么最好准备好一个出色的替代方案。 - ChrisNel52
1
是的。将嵌套的 try-catch 拆分为自己的方法是最好的选择。 - Sava B.

32

以下是一个案例:

try{
    //Dangerous Operation
} catch (AnyException ae) {
    try {
        //Do rollback which can fail
    } catch (RollbackFailedException rfe) {
        //Log that
    }
} finally {
    try {
        //close connection but it may fail too
    } catch (IOException ioe) {
        //Log that
    }
}

这跟 @x0n 说的差不多。在尝试关闭资源或者解决由其他异常引起的情况时,可能需要处理异常。


有更加简洁的方式来处理这个问题吗? - Arpit Agrawal
@ArpitAgrawal 使用像 Polly 这样的高级异常/尝试/重试管理包。 - x0n

29

不知道代码的作用是什么就无法判断。但这并不是 不寻常 的做法。

例如,如果您在处理异常时必须清除资源,则清除代码本身可能具有引发异常的能力。


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