views:

89

answers:

7

This is a bit abstract, but is there any possible way to throw an exception and have it enter multiple catch blocks. IE if it matches a specific exception followed by a non specific.

catch(Arithmetic exception)
{
  //do stuff
}
catch(Exception exception)
{
  //do stuff
}

I don't really NEED to do this I just need to this I just am wondering if it is possible.

+9  A: 

It is perfectly acceptable to have multiple catch blocks of differring types. However, the behavior is that the first candidate block handles the exception.

It will not enter BOTH catch blocks. The first catch block that matches the exception type will handle that specific exception, and no others, even if it's rethrown in the handler. Any subsequent ones will be skipped once an exception enters a catch block.

In order to have an exception caught in BOTH blocks, you would need to either nest blocks like so:

try
{
     try
     {
        // Do something that throws  ArithmeticException
     }
     catch(ArithmeticException arithException)
     {
        // This handles the thrown exception....

        throw;  // Rethrow so the outer handler sees it too
     }
}
catch (Exception e)
{
   // This gets hit as well, now, since the "inner" block rethrew the exception
}

Alternatively, you could filter in a generic exception handler based on the specific type of exception.

Reed Copsey
Nesting works ok for simple, one-level hierarchies but can ugly in a hurry if you have shared code that needs to run for several different exception cases. This isn't a disagreement with the approach, but an observation that it's not always appropriate.
tvanfosson
@tvanfosson: Yes, which is why I also added the filtering option. Your option is very nice, as well.
Reed Copsey
A: 

I don't think this is possible.

A_Nablsi
-1, how did this get up voted twice? It doesn't provide any information.
Malfist
I think this answers the question and someone was satisfied with it.
A_Nablsi
+7  A: 

No. It isn't possible to execute the code in both catch blocks for a single exception.

I would probably refactor the code in the generic exception block into something that can be called from either.

try
{
   // blah blah blah
{
catch(Arithmetic ae)
{
   HandleArithmeticException( ae );
   HandleGenericException( ae );
}
catch(Exception e)
{
  HandleGenericException( e );
}
tvanfosson
+1  A: 

You can't have more than one exception block handle the same exception. But what you can do is catch the general exception, then attempt to cast to the more specific, like this:

catch (Exception exception)
{
    var aex = exception as ArithmeticException
    if (aex != null)
    {
        // do stuff specific to this exception type
    }
  // then do general stuff
}
Kyralessa
A: 

This is known as exception filtering and isn't supported in C# (I'm told it is possible in VB.Net). One work around would be to catch the general exception and then check the exception type in the catch block and do any specific processing on that before carrying on with the rest of the block.

EDIT

I was about to paste a code sample but I see Kyralessa has already done that:-)

Steve Haigh
A: 

Like others said the exception will be caught by the most specific catch block.

This brings up a frustration of mine though with exception handling. I wish you could do something like

catch (ArgumentNullExcpetion, ArugmentOutOfRangeException ex)
{

}

Instead of having to do

catch (ArgumentNullExcpetion e)
{
}
catch (ArugmentOutOfRangeException outOfRange)
{
}

I understand the reasoning against this that you probably do different things for different exceptions but sometimes I want combine them.

Foovanadil
Don't both of those derive from ArgumentException -- if you really want to do the same thing for both, just catch ArgumentException. If you want to catch just the child exceptions, then you'd need to filter (and re-throw) ArgumentException using conditional logic. Your general point is good, but this isn't the best example. Maybe something like ValidationException (model error) and SqlException (constraint violation) where they aren't in the same hierarchy is a better example.
tvanfosson
I dont think your 100% right when you say "the exception will be caught by the most specific catch block" That is also dependent on order. So if you have a catch all first everything will always fall into that even if you have more specific ones after it
jon
tvanfosson. Good catch. I just made this example up on the fly. You are right I could catch the general parent exception in this case. But yeah I would like a way to catch multiple non related exception types in one catch block
Foovanadil
Good point Jon, you are correct it is order dependent. Another reason why multiple exceptions in one catch block would be nice, to eliminate the order dependency
Foovanadil
@tvanfosson: Catch-and-rethrow is evil, though in C# it's probably unavoidable. There are a number of circumstances where vb's "Catch When" is useful--I wonder why C# implementers so steadfastly refuse to implement it?
supercat
+1  A: 

If you were using VB.NET you could abstract your error handler in the Arithmatic exception into a function or method call that always returns false.

Then you could write something like:

Catch ex as Arithmetic When HandleArithmetic() Catch ex as Exception

End Try

Not that I would advocate such usage, though I have seen it recommended for logging purposes before. I don't believe there is a C# equivilent.

wllmsaccnt