I suggest you ...

I wish catch multiple exceptions in the same catch

For example:

try
{
// smth}
catch (RemoteException, NamingException , CreateException e)
{
// smth
}

1,631 votes
Vote
Sign in
Check!
(thinking…)
Reset
or sign in with
  • facebook
  • google
    Password icon
    I agree to the terms of service
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    Eric DelahayeEric Delahaye shared this idea  ·   ·  Flag idea as inappropriate…  ·  Admin →

    54 comments

    Sign in
    Check!
    (thinking…)
    Reset
    or sign in with
    • facebook
    • google
      Password icon
      I agree to the terms of service
      Signed in as (Sign out)
      Submitting...
      • Anonymous commented  ·   ·  Flag as inappropriate

        @KindDragon yes - you are right. I didn't see your example code when I responded. That syntax actually is quite clean and removes the ambiguity of what 'e's type could be

      • Anonymous commented  ·   ·  Flag as inappropriate

        @kinddragon those exceptions where just an example - not every use case is going to have a base exception type that is common only to the exceptions you care about and not all exceptions...that catch statement works in this case, but not all cases where this suggestion would be applicable

      • KindDragonKindDragon commented  ·   ·  Flag as inappropriate

        AppException is base class for RemoteException, NamingException and CreateException.

        My suggestion:
        try
        {
        // smth
        } catch (AppException e)
        where e : RemoteException || NamingException || CreateException
        {
        Debug.WriteLine(e.Message);
        // smth
        }

      • Arjan DouwesArjan Douwes commented  ·   ·  Flag as inappropriate

        Alternatively you could catch the generic Exception and filter on the string name of the type of exception using a switch case construct. For example:

        try
        {
        ////Do some work
        }
        catch (Exception e)
        {
        string exceptionTypeName = e.GetType().ToString();
        switch (exceptionTypeName)
        {
        case "System.ArgumentNullException":
        case "System.DivideByZeroException":
        ////Handle Arithmic related exceptions
        break;
        case "System.InvalidCastException":
        case "System.InvalidOperationException":
        ////Handle invalid typed exceptions
        break;
        case "MyNameSpace.MyCustomException":
        ////Handle the application's custom exception
        break;
        default:
        ////Rethrow the exception because something else went wrong...
        throw;
        }
        }
        finally { ////Clean up code }

      • Anonymous commented  ·   ·  Flag as inappropriate

        @decebalmihailescu Likely what would happen is that the 'e' variable defined at the end of the catch parenthesis would be of type 'Exception'. The idea is that there are times when you need to handle two exceptions the same way, but you don't want to swallow the exception if it's not of those types.

        i.e the following (which is kludgy and not clean):

        catch (Exception e)
        {
        if (!(e is RemoteException) && !(e is NamingException) && !(e is CreateException))
        throw;
        myLogger.Log("Handling a special case we care about")
        }

        can now become the following:

        catch (RemoteException, NamingException , CreateException e)
        {
        myLogger.Log("Handling a special case we care about")
        throw; //Throw if you don't want to swallow the exception
        }

        If you need to handle one exception type differently from the others, you wouldn't use this block...this would be for shared logic only

        i.e.:

        catch (RemoteException, NamingException , CreateException e)
        {
        myLogger.Log("Handling a special case we care about")
        throw; //Throw if you don't want to swallow the exception
        }
        catch (RemoteException e)
        {
        //Handle the remote exception individually
        }

      • decebal mihailescudecebal mihailescu commented  ·   ·  Flag as inappropriate

        Be careful what you wish for!
        Which kind of exception should you use in the catch handler?
        RemoteException, NamingException or CreateException?
        My guess is that you will use a superclass for all, and that might be System.Exception.
        So your fancy catch handler ends up being a lame catch(Exception e)....not a lot of achievements, isn't it.
        An easy work around: write your own method that you put in each catch block.

      • Anonymous commented  ·   ·  Flag as inappropriate

        wow, glad to see there is still innovation and discussion among professionals...

      • SleeperSmithSleeperSmith commented  ·   ·  Flag as inappropriate

        Oh **** off. Where's the down-vote button?

        I have not encountered a single instance where I catch multiple .net exceptions and handle them the same way. 5 years in industry.

        Outside of .net framework exceptions? USE INHERITANCE you moron.

        I'm lost for words.

      • Anonymous commented  ·   ·  Flag as inappropriate

        misunderstanding of what exceptions are for DETECTED
        fireing flamethrower if(flamethrowerfuel == empty){throw flamethrower instead;}

      • Anonymous commented  ·   ·  Flag as inappropriate

        @william

        Good point about the filtering...I didn't even think about using the filtering for anything other than the exception's type itself, that would actually be REALLY handy

        I also agree that using an 'is' check is a nice way of doing the task (that way they all would be able to be caught the same way.)

      • William BosackerWilliam Bosacker commented  ·   ·  Flag as inappropriate

        I think everyone needs to take a step back and look at what is truly trying to be accomplished here, the ability to handle multiple exception types in the exact same way. The key being, "the exact same way". If you use:

        catch (RemoteException, NamingException , CreateException ex)

        What type is the compiler going to use for ex? The compiler can only work if ex is of type Exception, which would be extremely confusing to say the least, as it doesn't match any other coding pattern. The closest pattern that would accommodate this would be:

        catch (Exception ex is RemoteException, NamingException , CreateException)

        or

        catch (BaseException ex is DerivedException1, DerivedException2, DerivedException3)

        Where the exceptions listed after the "is" clause must all derive from the BaseException. However, I do like the filtering that Mads brings up, so something like:

        catch (BaseException ex is DerivedException1, DerivedException2, DerivedException3)
        where (ex.Status == 1 || ex.Status == 2)

        Would work as well. This would fit in the C# language very easily, and the compiler would not have any trouble compiling it hard typed.

      • Anonymous commented  ·   ·  Flag as inappropriate

        this also avoids any nasty reflection-esque checks for what type the variable is

        I.E.

        try
        {
        //try logic
        }
        catch(Exception e) if (e is RemoteException || e is NamingException || e is CreateException)
        {
        //Do similar logic to all three
        //If I want to do anything with the RemoteException specifically now I have to do this
        if (e is RemoteException)
        {
        var re = (RemoteException)e;
        //Do something with the remote exception
        }
        }

        This seems to be a lot more verbose than it really needs to be...unless your exceptions are inherited from the same base class you will never see a filtered catch statement use anything but an 'or' statement, and if they are inherited from the same base class wouldn't you just catch the base class most of the time? That makes it kind of pointless to make us write an if check rather than making it a nice shorthand in the language

      • Anonymous commented  ·   ·  Flag as inappropriate

        @mads that is a really verbose way of doing it, plus it gets rid of any kind of nice static typing to the user so they would really need two if statements to handle the exception appropriately in some cases (one to filter the catch block and another to actually work with each type of exception)

        In reality, the issue (as I see it) is that the syntax is key to resolving the issue correctly. I like the proposed syntax in the question, but with the addition of typing each exception's type to it's own variable if desired.

        I.E. if you want all exceptions to be passed to variable 'e' then it would be the same as in the question:
        try
        {
        //try logic
        }
        catch (RemoteException, NamingException, CreationException e)
        {
        //catch logic
        }

        Otherwise, if you want to handle each exception differently in the catch body:

        try
        {
        //try logic
        }
        catch (RemoteException re, NamingException ne, CreationException ce)
        {
        //Do similar logic to all three or

        if (re != null)
        //Do something with the remote exception specifically

        if (ne != null)
        //Do something with the naming exception specifically

        //etc...etc...
        }

      • William BosackerWilliam Bosacker commented  ·   ·  Flag as inappropriate

        @Mads Torgersen: I was thinking something more similar to multiple usings for a block, or multiple case statements for a block, but your idea would be much more useful, especially if you would like to do something like filter web exceptions by status into separate blocks.

        It would also be great for custom exceptions that have a "Logged" property and you need to log the exception at a level that is much lower than where you present the exception to the user, and you don't want to log the exception twice.

        @llorracj: I have the same concern with the use of "if", but "where" would be a good choice.

      • llorracjllorracj commented  ·   ·  Flag as inappropriate

        I agree with Eric Delahaye. Using this approach you can have multiple catch blocks with different exceptions. Having multiple "if" statements doesn't seem consistent with try, catch, finally approach..

      • Mads Torgersen [MSFT]Mads Torgersen [MSFT] commented  ·   ·  Flag as inappropriate

        We have been looking at this on the C# design team.

        Several people have pointed out that this would be less of an issue if we had filtered exceptions like VB and F# do. If you could say

        catch(Exception e) if (e is RemoteException || e is NamingException || e is CreateException)
        { ... }

        Would that do the trick for you? You wouldn't have to catch/rethrow and you wouldn't have to write identical catch blocks for each specialized type of exception.

        Curious what people think?

        Thanks,

        Mads Torgersen [MSFT]

      ← Previous 1 3

      Feedback and Knowledge Base