C# tutorials > Core C# Fundamentals > Exception Handling > How do you handle multiple exceptions in a single `catch` block (exception filters)?

How do you handle multiple exceptions in a single `catch` block (exception filters)?

In C#, you can handle multiple exception types within a single catch block using exception filters. Exception filters provide a way to conditionally execute a catch block based on the specific characteristics of the exception being thrown. This allows for more granular and targeted exception handling compared to simply catching a base exception type.

Basic Syntax and Example

This example demonstrates how to catch FormatException and OverflowException separately using exception filters. The when keyword introduces the exception filter, which checks the exception's Message property to determine if the catch block should execute. If the condition in the when clause evaluates to true, the corresponding catch block is executed. The final catch block catches any other Exception types that aren't already handled.

csharp
try
{
    // Code that might throw exceptions
    Console.WriteLine("Enter a number:");
    string input = Console.ReadLine();
    int number = int.Parse(input);
    Console.WriteLine($"You entered: {number}");
}
catch (FormatException ex) when (ex.Message.Contains("Input string was not in a correct format."))
{
    Console.WriteLine("Error: Invalid input format. Please enter a valid number.");
}
catch (OverflowException ex) when (ex.Message.Contains("Value was either too large or too small"))
{
    Console.WriteLine("Error: The number you entered is too large or too small.");
}
catch (Exception ex)
{
    Console.WriteLine($"An unexpected error occurred: {ex.Message}");
}

Concepts Behind the Snippet

Exception filters are a powerful feature in C# that allow you to add conditional logic to your catch blocks. Instead of simply catching a specific exception type and handling it generically, you can examine the properties of the exception object and only execute the catch block if certain conditions are met. This enhances the precision and flexibility of your error handling strategy, enabling you to tailor your response to the specific circumstances of each exception. The when keyword allows you to add a boolean expression that determines whether the catch block will be executed.

Real-Life Use Case Section

Consider a scenario where you're reading data from a file. The file might be missing (FileNotFoundException), or its content might be corrupted leading to parsing errors (IOException or custom exception). Using exception filters, you can handle missing files differently from corrupted files, even if they both result in exceptions during the file reading process. For example, if the file is missing, you might try to create a default file. If the file is corrupted, you might log the error and prompt the user to fix the file.

csharp
try
{
    string content = File.ReadAllText("data.txt");
    // Process the content
} 
catch (FileNotFoundException ex) when (ex.Message.Contains("data.txt"))
{
    Console.WriteLine("File not found. Creating a default file...");
    File.WriteAllText("data.txt", "Default Data");
}
catch (IOException ex) when (ex.Message.Contains("corrupted") || ex.Message.Contains("invalid format"))
{
    Console.WriteLine("The file is corrupted. Please check the file.");
    // Log the error details
}
catch (Exception ex)
{
    Console.WriteLine($"An unexpected error occurred: {ex.Message}");
}

Best Practices

  • Avoid overly complex filters: Keep filters simple and focused on specific exception characteristics.
  • Use descriptive exception messages: Ensure that your custom exceptions have clear and informative messages, which can be used by the exception filters.
  • Don't overuse filters: If you find yourself using overly complex or numerous filters, consider restructuring your code or creating more specific exception types.
  • Consider logging: Log the specific details of the exception, including any values used in the exception filter, for debugging purposes.

Interview Tip

When discussing exception filters in an interview, highlight their ability to provide granular control over exception handling and their benefit in handling different scenarios related to the same exception type. Be prepared to explain the syntax of exception filters (catch (ExceptionType ex) when (condition)) and provide examples of their use. Mention that while powerful, they should be used judiciously to maintain code readability and avoid excessive complexity.

When to use them

Use exception filters when you need to handle different scenarios related to the same exception type. For example, if you're catching a SqlException, you might use exception filters to handle different SQL error codes (e.g., connection errors, constraint violations). This allows you to provide more specific error messages and take appropriate actions based on the exact cause of the exception. Another valid scenario is when you have a common library and you want to add a specific treatment, based on context, without modifying the library.

Memory footprint

Exception filters generally have a minimal impact on memory footprint. The primary memory consumption comes from the exception object itself, and the exception filter simply evaluates a boolean expression on that object. The added overhead is negligible in most cases. Avoid overly complex logic within the exception filter as it might impact performance but not memory usage.

Alternatives

An alternative to exception filters is to use multiple catch blocks, each catching a specific exception type. However, this can lead to code duplication if you need to perform similar actions for multiple exception types. Another alternative is to re-throw the exception within the catch block after performing some initial processing, but this can make the code more difficult to follow. Using a specific exception type, instead of generic exception with filters, is also a valid approach.

Pros

  • Granular Control: Allows for more specific handling of exceptions based on their properties.
  • Code Clarity: Can reduce code duplication compared to using multiple catch blocks.
  • Improved Error Handling: Enables more tailored error messages and actions based on the specific cause of the exception.

Cons

  • Complexity: Overuse of exception filters can make code harder to read and maintain.
  • Performance: Complex filters can impact performance, although this is usually minimal.
  • Debugging: Debugging can be more challenging if the logic within the filter is complex.

FAQ

  • Can I use exception filters with custom exceptions?

    Yes, you can use exception filters with custom exceptions. Just make sure your custom exception has properties that can be used in the filter condition.
  • Are exception filters supported in all versions of C#?

    Exception filters were introduced in C# 6.0, so they are not supported in earlier versions.
  • Can I use multiple conditions in an exception filter?

    Yes, you can use multiple conditions in an exception filter using logical operators like && (AND) and || (OR).