0
0
CppHow-ToBeginner · 3 min read

How to Catch Multiple Exceptions in C++: Syntax and Examples

In C++, you catch multiple exceptions by writing separate catch blocks for each exception type after a try block. Alternatively, you can catch multiple exceptions in one block using a common base class or by catching std::exception to handle many exceptions generally.
📐

Syntax

Use a try block to wrap code that might throw exceptions. Follow it with multiple catch blocks, each handling a specific exception type. The first matching catch block runs.

  • try: Code that may throw exceptions.
  • catch(Type1 &e): Handles exceptions of Type1.
  • catch(Type2 &e): Handles exceptions of Type2.
  • Order matters: more specific exceptions should come before general ones.
cpp
try {
    // code that may throw
} catch (const ExceptionType1 &e) {
    // handle ExceptionType1
} catch (const ExceptionType2 &e) {
    // handle ExceptionType2
} catch (const std::exception &e) {
    // handle other standard exceptions
}
💻

Example

This example shows catching two different exceptions: std::out_of_range and std::invalid_argument. Each catch block handles its exception type separately.

cpp
#include <iostream>
#include <stdexcept>

int main() {
    try {
        int choice = 2;
        if (choice == 1) {
            throw std::out_of_range("Out of range error");
        } else if (choice == 2) {
            throw std::invalid_argument("Invalid argument error");
        }
    } catch (const std::out_of_range &e) {
        std::cout << "Caught out_of_range: " << e.what() << '\n';
    } catch (const std::invalid_argument &e) {
        std::cout << "Caught invalid_argument: " << e.what() << '\n';
    } catch (const std::exception &e) {
        std::cout << "Caught std::exception: " << e.what() << '\n';
    }
    return 0;
}
Output
Caught invalid_argument: Invalid argument error
⚠️

Common Pitfalls

Common mistakes include:

  • Using a single catch(...) block without specific handling, which hides exception details.
  • Placing a general catch(const std::exception &e) before specific exceptions, causing specific handlers to never run.
  • Not catching exceptions by reference, which can cause slicing and lose information.
cpp
/* Wrong way: general catch before specific */
try {
    throw std::out_of_range("error");
} catch (const std::exception &e) {
    // This will catch all std exceptions first
    std::cout << "General catch: " << e.what() << '\n';
} catch (const std::out_of_range &e) {
    // This block will never run
    std::cout << "Out of range catch: " << e.what() << '\n';
}

/* Right way: specific catches first */
try {
    throw std::out_of_range("error");
} catch (const std::out_of_range &e) {
    std::cout << "Out of range catch: " << e.what() << '\n';
} catch (const std::exception &e) {
    std::cout << "General catch: " << e.what() << '\n';
}
📊

Quick Reference

Tips for catching multiple exceptions in C++:

  • Use multiple catch blocks after one try.
  • Catch exceptions by const reference to avoid slicing.
  • Order catch blocks from most specific to most general.
  • Use catch(...) only as a last resort to catch all exceptions.

Key Takeaways

Use multiple catch blocks to handle different exception types separately.
Always catch exceptions by const reference to preserve information.
Order catch blocks from specific exceptions to general ones.
Use catch(...) only to catch exceptions you cannot otherwise handle.
Catching std::exception covers many standard exceptions in one block.