从异常捕获中重新抛出异常

时间:2011-02-14 20:06:29

标签: .net vb.net exception-handling

捕获异常然后抛出另一个异常是一个好主意吗?

像这样:

Try
    ' Do operation xxx
Catch ex As Exception
    ' Operation xxx failed, need to execute cleanup
    ' But now I've caught this exception outside of my main control logic, 
    ' so I would like to re-throw it
    Throw New ApplicationException("XXX failed")
End Try

这样做的原因是,当我在更高级别的逻辑上捕获异常时(为了确保我可以正确记录它),我需要做一些操作,如果我只能在我的内部执行异常操作类/函数。

你能想出为什么这会是一个坏主意的原因/场景吗?

3 个答案:

答案 0 :(得分:10)

是的,这是一个坏主意。

首先,不要捕获异常以执行清理。使用Finally块,因为无论是否发生异常都将执行。你也不需要抛出一个新的例外只是为了说“XXX失败”。堆栈跟踪将显示。

其次,请勿使用ApplicationException。 Microsoft曾经建议用户定义的异常派生自ApplicationException,但结果却是个坏主意。他们现在建议我们使用Exception

最后,当你因为旧的异常而抛出一个新的异常时,一定要包含旧的异常:

Throw New Exception("My new message", ex)

答案 1 :(得分:1)

几点。首先,我同意John Saunders关于finally的使用。你真的应该在那里进行清理。

其次,如果要抛出新异常,则只需抛出异常或基于Exception创建自己的异常类型。如果您正在捕获I / O或SQL之类的低级异常,并且想要重新抛出正在执行的操作的某些特定内容,我建议您这样做。在这种情况下,您可能希望将捕获的异常嵌套为InnerException。寻找构造函数重载来轻松完成此任务。

第三,如果你想重新抛出我相信你可以写“throw”,它会隐式抛出当前捕获的异常。至少这就是你在C#中的做法,它允许异常及其整个堆栈跟踪和其他数据继续冒泡堆栈。

答案 2 :(得分:0)

这不一定是个坏主意。如果一个特定的异常对你的方法的调用者没有意义,因为它与调用者不知道的低级细节有关,那么最好将异常包装在一个新的异常中,该异常解释了来电做错了。

我还想补充一点,99%的时间你应该捕获特定的异常,而不是一般的Exception类型。如果您捕获所有异常,您很可能会隐藏您不准备处理的故障。最好让你的程序崩溃并告诉你出了什么问题,不知道为什么你的程序工作不正常。