Denis
Denis

Reputation: 12077

How can I implement a handler method for exceptions correctly?

Suppose I have the following construct:

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

And I would like to write handleException(ex). Suppose my class has different options of handling events:

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

Below is my attempt at writing "handleException". It seems no matter what I do, if the object was set with Exception mode of "ThrowToCaller" then the stack trace gets all messed up when I use handleException(). How can I just have a clean stack trace generated when the option is "ThrowToCaller" (every other option seems like it is working fine)

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

Upvotes: 4

Views: 149

Answers (2)

Jouke van der Maas
Jouke van der Maas

Reputation: 4318

Try changing the call to

if (!HandleException(ex)) throw;

and HandleException() to

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

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

That should do the trick.

Upvotes: 2

eulerfx
eulerfx

Reputation: 37719

To retain the stack trace of an exception in a catch block it has to be thrown with the following syntax (in C#, not familiar with 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;

}

}

Take a look at the exception handling block to get an idea of best practices of exception handling.

EDIT: Take a look at the answers here to find ways to preserve stack trace.

EDIT #2 I think part of the issue here is that this is not the best way to handle exceptions for the use case at hand. From the looks of it, this looks like GUI code due to the message box. The decision to display a message box should be made outside of this particular catch block. One way would be to use AOP to inject a message box handler for certain operations and certain exception types. The catch-rethrow scenario typically applies when you want to log the exception. At this point, you can have an interim solution by extracting the stack trace using reflection, but in the future consider refactoring your exception handling model.

Upvotes: 2

Related Questions