代码之家  ›  专栏  ›  技术社区  ›  Stefan

为什么捕获异常只是为了再次抛出它?

  •  13
  • Stefan  · 技术社区  · 16 年前

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

    <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
    

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

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

    7 回复  |  直到 10 年前
        1
  •  46
  •   GEOCHET S.Lott    16 年前

    不要这样做。

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

        2
  •  15
  •   S.Lott    16 年前

        3
  •  5
  •   tvanfosson    16 年前

    可能是调试过程中遗留的一些代码(您在抛出时设置了一个断点,以便在调试器中检查异常)。如果我想记录异常,然后将其传递到链上,我可能会这样做,尽管我可能会将异常包装到另一个异常中,并显示一条更有意义的(对我的应用程序而言)错误消息。

        4
  •  4
  •   Peter Mortensen icecrime    10 年前

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

    现在,将代码重构到一个更理智的状态。

        5
  •  0
  •   Jay    10 年前

    不仅try/catch没有意义,IF也没有意义。整个功能可以简化为一行:

    return successful
    

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

    (是的,我知道我的答案晚了7年。我只是在寻找完全无关的东西时偶然发现了这一点。)

        6
  •  0
  •   djv    9 年前

    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
    
        7
  •  0
  •   Nathan    5 年前

    一旦抛出异常,它所携带的部分信息就是堆栈跟踪。堆栈跟踪是一个方法调用层次结构的列表,它以抛出异常的方法开始,以捕获异常的方法结束。如果通过在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

        8
  •  0
  •   Chase    5 年前

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

    请记住,在一个完整的堆栈环境中,堆栈应该是独立的,并且不知道彼此的内部功能,同样,它们也不应该假设知道堆栈本身以外的堆栈处理捕获的异常的方式。实时处理异常并将其传递给调用方是一件非常有用的事情。

    总是用“扔”,而不是“扔”。Throw将重新生成句柄异常,使其堆栈保持完整。

        9
  •  -9
  •   Peter Mortensen icecrime    10 年前

    例如

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