Catch two exceptions in the same catch block?

66,060

Solution 1

In fact, you could catch only SystemException and it would handle CommunicationException too, because CommunicationException is derived from SystemException

catch (SystemException se) {
   ... //this handles both exceptions
}

Solution 2

If you can upgrade your application to C# 6 you are lucky. The new C# version has implemented Exception filters. So you can write this:

catch (Exception ex) when (ex is CommunicationException || ex is SystemException) {
    //handle it
}

Some people think this code is the same as

catch (Exception ex) {                
    if (ex is CommunicationException || ex is SystemException) {
        //handle it
    }
    throw;
}

But it´s not. Actually this is the only new feature in C# 6 that is not possible to emulate in prior versions. First, a re-throw means more overhead than skipping the catch. Second, it is not semantically equivalent. The new feature preserves the stack intact when you are debugging your code. Without this feature the crash dump is less useful or even useless.

See a discussion about this on CodePlex. And an example showing the difference.

Solution 3

Unfortunately, there is no way. The syntax you used is invalid and a fall through like in a switch-statement isn't possible either. I think you need to go with the private method.

A little hacky work-around would be something like this:

var exceptionHandler = new Action<Exception>(e => { /* your three lines */ });
try
{
    // code that throws
}
catch(CommuncationException ex)
{
    exceptionHandler(ex);
}
catch(SystemException ex)
{
    exceptionHandler(ex);
}

You need to decide for yourself if this makes any sense.

Solution 4

No, you can't do it that way. The only way i know of is to catch a generic Exception and then check what type it is:

try
{
   ...
}
catch(Exception ex)
{
   if(ex is CommunicationException || ex is SystemException)
   {
      ...
   }
   else
   {
     ... // throw; if you don't want to handle it
   }
}

Solution 5

What about

try {


...
}

catch (CommunicationException ce) {
   HandleMyError(ce);
}

catch {SystemExcetion se) {
   HandleMyError(se);
}

private void HandleMyError(Exception ex)
{
// handle your error
}
Share:
66,060
RoflcoptrException
Author by

RoflcoptrException

Updated on June 25, 2021

Comments

  • RoflcoptrException
    RoflcoptrException almost 3 years

    I have a method that can throw two different exceptions, CommuncationException and SystemException. In both cases I do the same three-line code block.

    try {
     ...
    }
    
    catch (CommunicationException ce) {
       ...
    }
    
    catch {SystemExcetion se) {
       ... 
    }
    

    Is there any possibility to do it like that?

    try {
       ...
    }
    
    catch (CommunicationException ce, SystemException se) {
       ...
    }
    

    Then I would not have to write this much code. I know I could extract the exception handling to a private method, but since the code is only 3 lines long, the method definition would take more code than the body itself.

  • Daniel Hilgarth
    Daniel Hilgarth about 13 years
    This changes the call stack of the exception. Not really what you want to.
  • Daniel Hilgarth
    Daniel Hilgarth about 13 years
    +1: In his specific case, that would be the way to go. Good catch!
  • RoflcoptrException
    RoflcoptrException about 13 years
    Yes that would be possible, but is it also good practice? I would also catch all the other subclasses without explicitly knowing it?
  • Daniel Hilgarth
    Daniel Hilgarth about 13 years
    You do that anyway, because you already catch SystemException.
  • RoflcoptrException
    RoflcoptrException about 13 years
    Omg yes ;) I never thought of that. Then the first catch is quite useless.
  • archil
    archil about 13 years
    No, it would not be good practice, cause it'll catch MASS of exceptions. But as Daniel mentioned, you already do that if it's not CommunicationException :)
  • Daniel Hilgarth
    Daniel Hilgarth about 13 years
    I don't agree with the solution provided in that question for the same reason I don't support alexn's answer. It is indeed the same answer as alexn already gave...
  • RoflcoptrException
    RoflcoptrException about 13 years
    Why does this change the call stack if I just use throw in the else statement?
  • Daniel Hilgarth
    Daniel Hilgarth about 13 years
  • Gerrie Schenck
    Gerrie Schenck about 13 years
    He doesn't want to do that :p
  • Marshal
    Marshal about 13 years
    @Daniel: Hmmm..nice to know that it changes the call stack and might not work properly.
  • Daniel Hilgarth
    Daniel Hilgarth about 13 years
    Yeah, where did he specify that? ;-) He just doesn't want to create a private method because of the code overhead it creates. This overhead is greatly reduced in my sample. But anyway, my main answer is, that he just can't do what he wants to do... I don't provide him with a "solution" he already dismissed in his question.
  • RoflcoptrException
    RoflcoptrException about 13 years
    Thanks a lot, I always thought I should just avoid using throw ex
  • Gerrie Schenck
    Gerrie Schenck about 13 years
    I know, just having a laugh :)
  • reads0520
    reads0520 over 6 years
    As the up votes reflect, this is a better answer to the question. The accepted answer correctly addresses the code sample given but does not answer the question asked.
  • florien
    florien over 6 years
    Yeah, this code is not the best, as it catches every kinds of SystemException, not only the desired two ones. You might want all the rest to not be caught in this try-catch!
  • florien
    florien over 6 years
    It is important in this solution that it re-throws all the rest-type exceptions!
  • Jorn.Beyers
    Jorn.Beyers over 5 years
    That's right, you should avoid using "throw ex;", but it's not what he is doing, he's keeping the original exception info by using "throw;"