Exception Handling
Learn how to handle errors gracefully using C++ exception handling mechanisms
Learn how to handle runtime errors gracefully using C++ exception handling with try, catch, and throw.
A Simple Example
#include <iostream>
#include <stdexcept>
double divide(double numerator, double denominator) {
if (denominator == 0.0) {
throw std::runtime_error{"Division by zero"};
}
return numerator / denominator;
}
int main() {
try {
double result{divide(10.0, 0.0)};
std::cout << "Result: " << result << "\n";
} catch (const std::runtime_error& e) {
std::cerr << "Error: " << e.what() << "\n";
}
std::cout << "Program continues...\n";
return 0;
}
Breaking It Down
try Block - Protected Code
- What it does: Wraps code that might throw exceptions
- Syntax: Place potentially failing code inside try { }
- Use for: File operations, network calls, calculations that might fail
- Remember: Without try-catch, exceptions cause program termination
throw - Raising Exceptions
- What it does: Signals an error condition by throwing an exception object
-
Syntax:
throw std::runtime_error{"Error message"}; - Common types: std::runtime_error, std::invalid_argument, std::out_of_range
- Remember: When thrown, execution immediately jumps to the nearest catch block
catch Block - Error Handling
- What it does: Catches and handles exceptions by type
-
Syntax:
catch (const std::exception& e) { /* handle */ } - Always use: const reference to avoid slicing and unnecessary copies
- Remember: Catch blocks are evaluated top to bottom - most specific first
Stack Unwinding - Automatic Cleanup
- What it does: Automatically destructs local objects when exception is thrown
- How it works: All objects in scope between throw and catch are destroyed
- Benefit: Resources are automatically cleaned up (files closed, memory freed)
- Remember: This is why RAII works perfectly with exceptions
Why This Matters
- Real-world programs encounter errors: files don't exist, networks fail, memory runs out. Without exception handling, your program crashes.
- Exception handling separates error-handling code from normal logic, making your programs more maintainable and reliable.
- Production code must handle failures gracefully, not crash and lose user data. Proper exception handling is the difference between a professional application and a toy program.
Critical Insight
Exceptions use stack unwinding, which means all local objects get destructed automatically when an exception is thrown. This is why RAII (which you'll learn about soon) works so beautifully with exceptions - resources are automatically cleaned up even when errors occur.
Think of it like dominoes falling backward: when an exception is thrown, every object created since entering the try block gets destroyed in reverse order. Your file handles close, your memory gets freed, your locks release - all automatically!
Best Practices
Always catch by const reference: Use catch (const std::exception& e) to avoid slicing and expensive copies.
Order catch blocks correctly: Place most specific exceptions first, then more general ones. Otherwise, specific exceptions will never be caught.
Never throw in destructors: Throwing exceptions from destructors during stack unwinding causes program termination.
Use standard exception types: Prefer std::runtime_error, std::invalid_argument, std::out_of_range instead of throwing raw strings or integers.
Common Mistakes
Catching by value: catch (std::exception e) creates an expensive copy and can cause slicing. Always use const reference.
Empty catch blocks: Never use catch (...) {} without at least logging the error. Silent failures are debugging nightmares.
Wrong catch order: Putting catch (std::exception&) before catch (std::runtime_error&) means the specific handler is never reached.
Throwing in destructors: Never throw exceptions from destructors - it can cause program termination during stack unwinding.
Debug Challenge
This exception handler has a common bug. Click the highlighted line to fix how the exception is caught:
Quick Quiz
- What happens if an exception is thrown but not caught?
- Which is the correct way to catch exceptions?
- What is the order of catch blocks from most specific to most general?
Practice Playground
Time to try out what you just learned! Play with the example code below, experiment by making changes and running the code to deepen your understanding.
Output:
Error:
Lesson Progress
- Fix This Code
- Quick Quiz
- Practice Playground - run once