C++ - Error Handling & Exceptions
Overview
Estimated time: 45–65 minutes
Use exceptions for error reporting in exceptional, non-local situations. Learn try/catch, standard exceptions, noexcept, and exception-safety with RAII.
Learning Objectives
- Throw and catch exceptions; use standard exception types.
- Understand noexcept and when to use it.
- Design code with RAII so resources are released on exception paths.
Prerequisites
Throw and catch
#include <stdexcept>
#include <iostream>
int parse_positive(int x){ if (x <= 0) throw std::invalid_argument("non-positive"); return x; }
int main(){
try {
std::cout << parse_positive(1) << "\n";
std::cout << parse_positive(0) << "\n"; // throws
} catch (const std::invalid_argument& e) {
std::cout << "error: " << e.what() << "\n";
}
}
Expected Output:
1
error: non-positive
noexcept and strong exception safety
#include <vector>
#include <iostream>
void may_throw(){ throw 42; }
void safe() noexcept { /* won't throw */ }
int main(){
try { may_throw(); } catch(...) { std::cout << "caught\n"; }
safe();
}
RAII to the rescue
#include <fstream>
#include <string>
#include <iostream>
void write_line(const std::string& path){
std::ofstream out(path); // closed automatically even if exceptions occur later
if (!out) throw std::runtime_error("open failed");
out << "line\n";
}
Beginner Boosters
#include <stdexcept>
#include <string>
#include <iostream>
int to_int(const std::string& s){
for (char c: s) if (c < '0' || c > '9') throw std::invalid_argument("not a digit");
return std::stoi(s);
}
int main(){
try { std::cout << to_int("123") << "\n"; std::cout << to_int("1x") << "\n"; }
catch(const std::exception& e){ std::cout << e.what() << "\n"; }
}
Common Pitfalls
- Using exceptions for normal control flow; prefer return status for expected outcomes.
- Catching by value (slicing); catch exceptions by const reference.
- Forgetting RAII; leaking resources on throw paths.
Checks for Understanding
- When should you use exceptions vs return codes?
- Why catch exceptions by const reference?
Show answers
- Exceptions for exceptional, non-local errors; return codes for expected results.
- To avoid slicing and unnecessary copies; preserve dynamic type.
Exercises
- Write a function that opens a file and throws std::runtime_error on failure; write tests using try/catch.
- Mark a function noexcept and verify the compiler enforces it by preventing throws.