Catch multiple exceptions at once: C#

The try{} block serves as a designated section of code where exceptions may potentially arise. Following the try block, a catch{} block is employed to handle any exceptions that occur within the associated try block. It is possible for a single try block to be accompanied by multiple catch blocks, each tailored to handle different types of exceptions. This approach allows developers to efficiently manage various exceptional scenarios. However, the utilization of multiple catch blocks can sometimes result in redundant and repetitive code, leading to code maintenance challenges and reduced code elegance. To address this concern and enhance code readability and maintainability, developers often seek alternative strategies, such as exception hierarchies and polymorphism, to consolidate exception handling and minimize redundancy.


How to Catch multiple types of exceptions in one catch block
example
try { // try some stuff } catch (FormatException ex) { HandleIt(ex); } catch (OverflowException ex) { HandleIt(ex); } catch(Exception) { throw; }

In the above example there is some code duplication and it is better to avoid while catching exception.

Switch on the types

You can avoid this code duplication by catch System.Exception and handle the specific types; otherwise, throw the exception to be handled higher up in the code:

catch (Exception ex) { if (ex is FormatException ex is OverflowException) { // write to a log, whatever... return; } throw; }

C# Exception filters


C# Exception Handling Best Practices using Exception filters

Using catch arguments and exception filters are valuable techniques to precisely filter and handle specific exceptions in C#. Exception filters, introduced in C# 6.0, provide a powerful mechanism for further evaluating exceptions to determine whether a particular catch clause should be applied or not. These filters act as conditional clauses that control the application of catch clauses based on the result of an expression evaluation. If the expression in the exception filter returns true, the associated catch clause executes its designated error-handling logic. Conversely, if the expression evaluates to false, the catch clause is bypassed, allowing the exception to propagate further or be handled by subsequent catch blocks. This flexibility enables developers to create catch blocks that selectively handle exceptions based on specific conditions, streamlining error management and improving code conciseness. By utilizing exception filters, developers can ensure that exception handling is fine-tuned to meet specific requirements, leading to more robust and maintainable code. Syntax
catch (ArgumentException e) when (e.ParamName == "…") { }
example
try { // try some stuff } catch (MyException ex) when (ex.Code == 403) { HandleException(ex); }

Here the catch block will be entered if and only if ex.Code == 403. If the condition is not verified, the exception will bubble up the stack until it's caught somewhere else or terminates the process .

Thus, if we want to handle multiple types of exceptions in the same way using Exception Filters , we could write this:

try { // try some stuff } catch(MyException ex) when(ex.Code == 403 ex.Code == 404) { HandleException(ex); }

A common use of exception filter expressions is logging. You can create a filter that always evaluate false that also outputs to a log, you can log exceptions as they go by without having to handle them and rethrow.