Handling Multiple Exceptions in C# using Multiple `catch` Blocks

Learn how to gracefully handle different types of exceptions in C# using multiple `catch` blocks within a `try-catch` structure. This tutorial demonstrates creating specific exception handlers for various error conditions, improving code robustness and providing more controlled responses to runtime errors.



Handling Multiple Exceptions with Multiple `catch` Blocks in C#

Introduction

In C#, you can use multiple `catch` blocks within a `try-catch` structure to handle different types of exceptions. This allows you to respond to various error conditions in a more specific and controlled manner.

Understanding `catch` Blocks

A `catch` block is an exception handler. It specifies the type of exception it's designed to handle. When an exception occurs within a `try` block, the runtime searches for the first `catch` block whose exception type matches the thrown exception. If a match is found, that `catch` block's code executes.

Using Multiple `catch` Blocks

To handle multiple exception types, you simply list multiple `catch` blocks after a `try` block. Each `catch` block should specify a different exception type. The order of the `catch` blocks matters; the runtime checks them sequentially.

Syntax

Multiple `catch` Block Syntax

try {
    // Code that might throw exceptions
} catch (ExceptionType1 ex1) {
    // Handle ExceptionType1
} catch (ExceptionType2 ex2) {
    // Handle ExceptionType2
} catch (ExceptionType3 ex3) {
    //Handle ExceptionType3
}
// ...more catch blocks...

It's crucial that each `catch` block handles a *different* exception type. Trying to have multiple `catch` blocks for the same type will result in a compiler error.

Example 1: Handling `DivideByZeroException` and `IndexOutOfRangeException`

Example 1: Handling Division by Zero and Index Out of Range

using System;

class CatchExample {
    static void Main() {
        int[] numbers = { 18, 19, 28, 35, 56 };
        int[] divisors = { 9, 0, 1, 0, 10}; //Potential for exceptions

        for (int j = 0; j < numbers.Length; j++) {
            try {
                Console.WriteLine($"Number: {numbers[j]}, Divisor: {divisors[j]}, Quotient: {numbers[j] / divisors[j]}");
            } catch (DivideByZeroException) {
                Console.WriteLine("Division by zero is impossible.");
            } catch (IndexOutOfRangeException) {
                Console.WriteLine("Index out of range.");
            }
        }
    }
}

Example 2: Handling Multiple Exception Types

Example 2: Multiple Exception Types

using System;

class MultiCatchExample {
    static void Main() {
        try {
            byte val = byte.Parse("a");
            Console.WriteLine(val);
        } catch (IndexOutOfRangeException) {
            Console.WriteLine("Index out of range.");
        } catch (FormatException) {
            Console.WriteLine("Invalid format.");
        } catch (OverflowException) {
            Console.WriteLine("Value out of range for byte.");
        }
    }
}

Conclusion

Using multiple `catch` blocks provides a structured way to handle various exceptions gracefully. This improves code robustness and makes error handling more precise.