为什么只是再次抛出一个异常?

时间:2008-12-03 11:52:47

标签: vb.net web-services exception exception-handling

在网络服务中,我看到了这段代码:

<WebMethod()> _
Public Function dosomething() As Boolean
    Try
        If successful Then
            Return True
        Else
            Return False
        End If
    Catch ex As Exception
        Throw ex
    End Try
End Function

捕获异常并重新抛出异常有什么意义?我想念一下吗?

编辑: 谢谢你的回答!我认为这是类似的东西,但不确定我是否能够/将重构那些没有任何影响的人。

9 个答案:

答案 0 :(得分:43)

不要这样做。

如果你绝对需要重新抛出异常,只需使用throw;使用throw ex;擦除堆栈跟踪,绝对是错误的。

答案 1 :(得分:14)

我认为没有理由为功能做到这一点。但是,如果之前存在一些已删除的错误处理(通常是日志记录),并且开发人员删除了日志处理但未重组代码以删除冗余的try / catch,则会出现这种情况。

答案 2 :(得分:5)

可能是调试遗留下来的一些代码(你在throw上设置一个断点,这样你就可以检查调试器中的异常)。如果我想记录异常并将其传递给链接,我可能会做类似这样的事情,尽管我可能会将异常包装在另一个异常(对我的应用程序)错误消息中。

答案 3 :(得分:4)

我可以看到其中一个架构(design patterns)正在处理事务。该函数执行其工作,失败,并且catch块将事务完成到已知状态(通常是回滚),然后抛出用户定义的异常。

现在,将代码重构为更健全的状态。

答案 4 :(得分:1)

不仅try / catch无意义,IF也是如此。整个功能可以减少到一行:

return successful

在哪一点上,为什么要这么麻烦?为什么不测试“成功”而不是调用函数?

嗯,好吧,这是一个Web方法,我想你需要这个函数只是为了给Ajax或者任何一个句柄。

(是的,我知道我的答案已经晚了7年。在搜索完全不相关的内容时,我偶然发现了这一点。)

答案 5 :(得分:0)

Monitor的模式使得这很可能会重新抛出一个错误,因为你需要一个finally来确保调用Monitor.Exit

https://msdn.microsoft.com/en-us/library/4tssbxcw(v=vs.110).aspx

Dim lockObj As New Object()

If Monitor.TryEnter(lockObj) Then
    Try
        ' The critical section.
    Catch
       throw
    Finally
       ' Ensure that the lock is released.
       Monitor.Exit(lockObj)
    End Try
End If

答案 6 :(得分:0)

来自Microsoft的CodeAnalysis:(CA2200:重新提交以保留堆栈详细信息)

“一旦引发异常,它所携带的部分信息就是堆栈跟踪。堆栈跟踪是方法调用层次结构的列表,该列表以引发异常的方法开始并以捕获异常的方法结束如果通过在throw语句中指定异常来重新抛出异常,则堆栈跟踪将在当前方法处重新启动,并且抛出该异常的原始方法与当前方法之间的方法调用列表将丢失。原始堆栈跟踪信息以及异常,请使用throw语句而不指定异常。”

  Sub CatchAndRethrowImplicitly()
     Try
        ThrowException()
     Catch e As ArithmeticException
        ' Satisfies the rule.
        Throw
     End Try
  End Sub

https://docs.microsoft.com/en-us/visualstudio/code-quality/ca2200-rethrow-to-preserve-stack-details?view=vs-2019

答案 7 :(得分:0)

这样做的理由非常充分,尤其是在Full Stack / N Tier环境中。

在类库中尝试/捕获代码,记录异常并将其扔回调用应用程序以允许调用方以其想要的方式处理异常是有意义的。

请记住,在全栈环境中,栈应该是独立的并且不了解彼此的内部功能,同样,它们不应该假定知道栈本身(外部)想要处理捕获的异常的方式。实时处理异常,然后将其传递给调用方是一件非常有帮助的事情。

并且始终仅使用“ Throw”,而不是“ Throw ex”。抛出将重新抛出句柄异常,从而使其堆栈保持完整。

答案 8 :(得分:-8)

如果你想要捕获除它的子类之外的异常,你可能想要这样做。

例如,

try {
    // Something stupid
}
catch(RuntimeException e) {
    throw e; //Handle it outside
}
catch (Exception e) {
    // I'm dead
}