Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merge catch blocks with exactly the same code? [duplicate]

I want to merge the catch blocks in the following code for code reuse reasons:

try
{
    DoSomeInputOutput();
}
catch (InvalidOperationException ex)
{
    HandleKnownException1(ex);
}
catch (InvalidDataException ex)
{
    HandleKnownException1(ex);
}
catch (ArgumentNullException ex)
{
    HandleKnownException1(ex);
}
catch (ArgumentOutOfRangeException ex)
{
    HandleKnownException2(ex);
}
catch (ArithmeticException ex)
{
    HandleKnownException2(ex);
}
catch (InvalidCastException ex)
{
    HandleKnownException2(ex);
}
catch (Exception ex)
{
    HandleUnknownException(ex);
}

to something like this:

try
{
    DoSomeInputOutput();
}
catch (InvalidOperationException ex)
catch (InvalidDataException ex)
catch (ArgumentNullException ex)
{
    HandleKnownException1(ex);
}
catch (ArgumentOutOfRangeException ex)
catch (ArithmeticException ex)
catch (InvalidCastException ex)
{
    HandleKnownException2(ex);
}
catch (Exception ex)
{
    HandleUnknownException(ex);
}

Is that possible somehow?

Thanks.

like image 873
DxCK Avatar asked Dec 12 '09 12:12

DxCK


People also ask

Is there a way to catch multiple exceptions at once and without code duplication?

In C#, You can use more than one catch block with the try block. Generally, multiple catch block is used to handle different types of exceptions means each catch block is used to handle different type of exception.

Can multiple catch blocks of the same try catch finally statement be executed?

Yes you can have multiple catch blocks with try statement. You start with catching specific exceptions and then in the last block you may catch base Exception . Only one of the catch block will handle your exception. You can have try block without a catch block.

Can there be multiple catch in a single code?

You cannot have multiple try blocks with a single catch block. Each try block must be followed by catch or finally.

How do you handle multiple exceptions in single catch block?

If a catch block handles multiple exceptions, you can separate them using a pipe (|) and in this case, exception parameter (ex) is final, so you can't change it. The byte code generated by this feature is smaller and reduce code redundancy.


2 Answers

Presumably, you do it in more than one place. If so, why don't you do this:

{
    DoSomeInputOutput();
}
catch (Exception ex)
{
    HandleInputException(ex);
}

void HandleInputException(Exception ex)
{
   if (ex is InvalidOperationException || ex is InvalidDataException || ex is ArgumentNullException)
   {
     HandleKnownException1 (ex);
   }
   else if ...
   else if ...
}
like image 75
yu_sha Avatar answered Oct 20 '22 17:10

yu_sha


No (or at least: not unless the exceptions you want to group happen to share a common base-class specific to that group, which they don't in your example); the only thing you can do in this scenario is catch (Exception ex) and do runtime testing on ex. By the time you've done that, I expect your code is already "prettier" as-is (since, importantly, you've already refactored the handling code into a method).

I'd be tempted to tweak the spacing so I can focus on the important code:

try
{
    DoSomeInputOutput();
}
// blah humorous scenario 1
catch (InvalidOperationException ex) { HandleKnownException1(ex); }
catch (InvalidDataException ex) { HandleKnownException1(ex); }
catch (ArgumentNullException ex) { HandleKnownException1(ex); }
// blah whimsical scenario 2
catch (ArgumentOutOfRangeException ex) { HandleKnownException2(ex); }
catch (ArithmeticException ex) { HandleKnownException2(ex); }
catch (InvalidCastException ex) { HandleKnownException2(ex); }
// unexpected comedy
catch (Exception ex) { HandleUnknownException(ex); }

(or something).

In some ways this also ties into this question: switch / pattern matching idea.

like image 42
Marc Gravell Avatar answered Oct 20 '22 18:10

Marc Gravell