Rethrowing an exception in C++
In C++, "rethrowing an exception" refers to catching an exception in one section of code and then rethrowing it to be caught in a different section of code, frequently further up the call stack. This can be helpful when you wish to perform some cleanup or specific handling at a certain application level while propagating the exception higher up for more broad error handling.
The exception can be rethrown if a catch block cannot handle the specific one it has captured. The original object thrown is rethrown when the rethrow expression is used (throw without assignment_expression).
It is rethrown out to the following dynamically enclosing try block because the exception has already been captured at the scope where the rethrow statement appears. As a result, catch blocks at the scope where the rethrow expression happened cannot handle it. The exception may be caught by any catch blocks for the dynamically enclosing try block.
Here are three examples of a good understanding of the concept:
Example 1: Simple Rethrow Example
Code:
#include <iostream>
void someFunction() {
try {
// Simulate an exception
throw std::runtime_error("An error occurred!");
} catch (const std::exception& e) {
std::cout << "Caught exception: " << e.what() << std::endl;
//Rethrow the caught exception
throw; //Rethrows the same exception object
}
}
int main() {
try {
someFunction();
} catch (const std::exception& e) {
std::cout << "Caught exception in main: " << e.what() << std::endl;
}
return 0;
}
Output:
![Rethrowing an exception in C++](https://static.tutorialandexample.com/cpp/rethrowing-an-exception-in-cpp1.png)
Explanation:
- There is a declared function named someFunction(). This function contains a try block to capture exceptions of the std::exception and its derived classes.
- A std::runtime_error exception with the message "An error occurred!" is thrown within the try block.
- The catch block immediately follows the try block. It captures the thrown exception (of type const std::exception&). The parameter e is given ownership of the caught exception.
- A message stating that an exception was caught is printed to the console from the catch block. The error message connected to the caught exception is retrieved using the e.what() function and written to the console.
- The code reaches the line throw after producing the message. The exception that was initially caught is again thrown in this line. Simply, it propagates the exception up the call stack so that any higher-level catch blocks can handle it.
- The main() function is where the call to someFunction() is made before the program returns.
- Any exceptions of type std::exception and its related classes are caught in the catch block in the main() function. The error message connected to the captured exception is retrieved and printed using the e.what() function.
- Since the exception thrown in someFunction() is of type std::runtime_error, which derives from std::exception, it matches the catch block in both someFunction() and main().
Example 2: Code for Rethrowing Standard Exception
Code:
#include <iostream>
#include <stdexcept>
void innerFunction() {
try {
throw std::runtime_error("Inner Function Exception");
} catch (const std::exception& e) {
std::cout << "Inner Function caught exception: " << e.what() << std::endl;
throw; //Rethrow the same exception
}
}
void outerFunction() {
try {
innerFunction();
} catch (const std::exception& e) {
std::cout << "Outer Function caught exception: " << e.what() << std::endl;
}
}
int main() {
try {
outerFunction();
} catch (const std::exception& e) {
std::cout << "Main caught exception: " << e.what() << std::endl;
}
return 0;
}
Output:
![Rethrowing an exception in C++](https://static.tutorialandexample.com/cpp/rethrowing-an-exception-in-cpp2.png)
Explanation:
- std::runtime_error is thrown by the innerFunction() function.
- When an error occurs, innerFunction() catches it, prints a notice, and then uses throw to rethrow the same exception.
- Within outerFunction(), the rethrown exception is captured, and a message is printed again.
- The main() method finally catches the exception, and its message appears.
Example 3: Code for Rethrowing Custom Exception
Code:
#include <iostream>
class CustomException : public std::exception {
public:
const char* what() const noexcept override {
return "Custom Exception";
}
};
void processNumber(int num) {
if (num < 0) {
throw CustomException();
}
std::cout << "Number is valid." << std::endl;
}
int main() {
try {
processNumber(-5);
} catch (const CustomException& e) {
std::cout << "Main caught custom exception: " << e.what() << std::endl;
}
return 0;
}
Output:
![Rethrowing an exception in C++](https://static.tutorialandexample.com/cpp/rethrowing-an-exception-in-cpp3.png)
Explanation:
The main() method handles the exception, and a message is printed.
A number is passed as an integer to the processNumber() method.
The integer throws a CustomException if it is negative.