如何正确实现异常的处理程序方法?

时间:2011-07-05 18:31:10

标签: c# vb.net

假设我有以下构造:

Public Sub SomeMethod()
   Try
      doSomething()
   Catch ex as Exception
      handleException(ex)
   End Try
End Sub

我想编写handleException(ex)。假设我的班级有不同的处理事件的选项:

 Public Enum ExceptionHandlingType
        DisplayInMessageBox 'Display in msgbox
        ThrowToCaller       'Raise the error to the caller routine
        RaiseOnMessageEvent 'e-mail
    End Enum

以下是我写“handleException”的尝试。似乎无论我做什么,如果对象设置为“ThrowToCaller”的异常模式,那么当我使用handleException()时,堆栈跟踪会全部搞砸。如何在选项为“ThrowToCaller”时生成一个干净的堆栈跟踪(每个其他选项看起来工作正常)

Public Sub handleException(ex as Exception)
  Select Case mExceptionHandling
            Case ExceptionHandlingType.DisplayInMessageBox
                MsgBox(ex.Message)
            Case ExceptionHandlingType.ThrowToCaller
                Throw New Exception(ex.Message, ex)
            Case ExceptionHandlingType.RaiseOnMessageEvent
                SendEMailMessage(ex)
        End Select
End Sub

2 个答案:

答案 0 :(得分:2)

要在catch块中保留异常的堆栈跟踪,必须使用以下语法抛出它(在C#中,不熟悉VB):

try {
   // some operation ...
} 
catch (Exception ex) {

switch(mExceptionHandling) {

case ExceptionHandlingType.ThrowToCaller: throw;
case ExceptionHandlingType.DisplayInMessageBox: MsgBox(ex.Message); break;
case ExceptionHandlingType.RaiseOnMessageEvent: SendEmailMessage(ex); break;
default: throw;

}

}

查看exception handling block以了解异常处理的最佳做法。

修改 查看答案here以找到保留堆栈跟踪的方法。

编辑#2 我认为这里的部分问题是,这不是处理手头用例异常的最佳方法。从它的外观来看,由于消息框,它看起来像GUI代码。显示消息框的决定应该在此特定catch块之外进行。一种方法是使用AOP为某些操作和某些异常类型注入消息框处理程序。捕获 - 重新抛出场景通常适用于您要记录异常的情况。此时,您可以通过使用反射提取堆栈跟踪来获得临时解决方案,但在将来考虑重构您的异常处理模型。

答案 1 :(得分:2)

尝试将通话更改为

if (!HandleException(ex)) throw;

HandleException()

bool HandleException(Exception ex) {
    bool handled = false;

    if (ex is SomeException) {
        ... handle the exception ...
        handled = true
    }
    return handled;
}

这应该可以解决问题。