14

在网络服务中,我看到以下代码:

<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

捕获异常并再次抛出它有什么意义?我错过了什么吗?

编辑:感谢您的回答!我认为它是这样的,但不确定我是否可以/是否会在没有任何影响的情况下将它们重构掉。

4

9 回答 9

46

不要这样做。

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

于 2008-12-03T12:02:25.290 回答
15

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

于 2008-12-03T11:55:52.477 回答
5

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

于 2008-12-03T11:58:55.843 回答
4

我可以看到其中使用的架构(设计模式)之一是处理事务的地方。该函数完成它的工作,失败,catch 块将事务完成到一个已知状态(通常是回滚),然后抛出一个用户定义的异常。

就目前而言,将代码重构为更理智的状态。

于 2008-12-03T12:30:28.447 回答
0

不仅 try/catch 毫无意义,IF 也是如此。整个函数可以简化为一行:

return successful

在这一点上,为什么要打扰?为什么不只是测试“成功”而不是调用函数呢?

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

(是的,我知道我的答案晚了 7 年。我在搜索完全不相关的东西时偶然发现了这个。)

于 2015-06-09T21:13:20.903 回答
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
于 2016-05-20T12:43:20.940 回答
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

于 2019-08-09T14:25:28.703 回答
0

这样做有很好的理由,尤其是在全栈/N 层环境中。

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

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

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

于 2020-02-06T18:48:51.167 回答
-9

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

例如,

try {
    // Something stupid
}
catch(RuntimeException e) {
    throw e; //Handle it outside
}
catch (Exception e) {
    // I'm dead
}
于 2008-12-03T12:13:41.927 回答