Passing exception to a common sub

  • Thread starter Thread starter Young
  • Start date Start date
Y

Young

Instead of handling exception in each function/sub, I would like to pass the
exception to a sub and get it to handle all exceptions. Here's where I try
to do:

Try
.....

Catch Ex as Exception

Call HandleEx(Ex) ' HandleEx is the sub

end try

Here's HandleEx:

Sub HandleEx(Ex as Exception)
dim msg as string
msg = Ex.Message
Msgbox (Msg) ' This works.
end sub

How can I get the exception type within HandleEx? What I am trying to do is
this:

Sub HandleEx(Ex as Exception)

If TypeOf Ex Is System.ArgumentException Then

ElseIf TypeOf Ex Is System.IO.FileNotFoundException then

Endif

end sub

The above works but I can I do it in a Select Case statement instead of use
If TypeOf Ex Is?

Please Help.
Thanks
Young
 
Instead of handling exception in each function/sub, I would like to pass the
exception to a sub and get it to handle all exceptions. Here's where I try
to do:

Try
....

Catch Ex as Exception

    Call HandleEx(Ex)    ' HandleEx is the sub

end try

Here's HandleEx:

Sub HandleEx(Ex as Exception)
    dim msg as string
    msg = Ex.Message
    Msgbox (Msg)    ' This works.
end sub

How can I get the exception type within HandleEx? What I am trying to do is
this:

Sub HandleEx(Ex as Exception)

    If TypeOf Ex Is System.ArgumentException Then

    ElseIf TypeOf Ex Is System.IO.FileNotFoundException then

    Endif

end sub

The above works but I can I do it in a Select Case statement instead of use
If TypeOf Ex Is?

No, there's no "typeswitch" in VB (or C#, for that matter).

Also, in general, what you're doing is a bad idea. You should use
"catch" statement to filter on exception types, not catch everything
and then check the type.

One way you could do that and still retain genericity is to reverse
the pattern - instead of every method catching the exception and then
calling a generic "handler" method, you should make a generic method
that takes a delegate, executes that delegate, and catches/handles
everything as needed. E.g.:

Private Function InvokeAndHandle(Of T)(f As Func(Of T)) As T
Try
Return f()
Catch ex As ArgumentException
...
Catch ex As FileNotFoundException
...
End Try
End Function

Then you can call that from your methods:

' Public API entry point
Public Function Foo(x As Integer) As Integer
Return InvokeAndHandle(Function() FooNoCatch(x))
End Function

Private Function FooNoCatch(x As Integer) As Integer
' Actual code goes here
...
End Function

It's even easier with C#, where you aren't limited to expression
lambdas, and can just define anonymous delegates fully inline.
 
Young,

I agree for the most part of Pavel his message, you should not want this

But you can forever pass something as object.

However, in general it is bad practice to use object as a type and so it is
here.

Cor
 
Hi

Before main Form run
you can setup general catch for all your exceptions which will not be
handled in your code

static void Main()
{
CustomExceptionHandler eh = new CustomExceptionHandler();
Application.ThreadException += new
System.Threading.ThreadExceptionEventHandler(eh.OnThreadException);
}

internal class CustomExceptionHandler
{

// Handles the exception event.
public void OnThreadException(object sender,
System.Threading.ThreadExceptionEventArgs t)
{
DialogResult result = DialogResult.Cancel;
try
{
result = this.ShowThreadExceptionDialog(t.Exception);
}
catch
{
try
{
MessageBox.Show("Fatal Error.", "Fatal Error",
MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop);
}
finally
{
Application.Exit();
}
}

// Exits the program when the user clicks Abort.
if (result == DialogResult.Abort)
Application.Exit();
}

// Creates the error message and displays it.
private DialogResult ShowThreadExceptionDialog(Exception e)
{
string errorMsg = "An error occurred please contact the
adminstrator.\n\n";
errorMsg = errorMsg + e.Message;
//Data.op.log.WriteEntry(e.ToString(),
System.Diagnostics.EventLogEntryType.Error);
return MessageBox.Show(errorMsg, "Application Error",
MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop);
}
}
 
Young said:
Instead of handling exception in each function/sub, I would like to pass the
exception to a sub and get it to handle all exceptions.

IMHO, this is a Bad Idea.

The important part about Exception Handling is the "Handling" part, i.e.
doing something /useful/ about an Exception in the /context/ in which it
happens.

The same exception can be raised in many different places; take the
FileNotFoundException, for example. You could get this when:
(a) You try to read a user's "options" file for the very first time; no
big deal, you'll create it later, so you can safely catch (and choose to
ignore) this Exception.
(b) You try to open the "licence" file (that your installer created)
that states who is allowed to run your program. If that's missing, you
have a big problem and the program should stop dead.

Most importantly, you have to deal with (i.e. "handle") both of the
above cases (same Type of Exception, remember) in /completely/ different
ways.

Always try to keep your handling code as close to that which throws the
Exception(s) as you can, preferably within the same method.


That said, you can create an Application-level, catch-all Exception
Handler but (AFAIK) this will only be called just before your program
crashes and burns and the Run-Time tears it down and throws it away
(it's one stop short of the "a program has encountered a problem"
dialog, but only one).

Regards,
Phill W.
 
Back
Top