Open In App

Rethrowing an Exception in C++

Last Updated : 05 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Exception handling plays a role in developing robust software in C++. It offers a way to handle errors and unexpected situations. One interesting aspect of exception handling in C++ is the ability to rethrow an exception allowing it to pass up the call stack.

Rethrowing an Exception

Rethrowing an exception in C++ involves catching an exception within a try block and instead of dealing with it locally throwing it again to be caught by an outer catch block. By doing this. we preserve the type and details of the exception ensuring that it can be handled at the appropriate level within our program.

This approach becomes particularly valuable when managing exceptions at multiple levels or when additional actions need to be performed before resolving the exception.

To better understand how this works let’s explore an example involving three functions:

Example

C++




#include <iostream>
#include <stdexcept>
using namespace std;
  
// Function to perform division
int divide(int numerator, int denominator)
{
    try {
        if (denominator == 0) {
            // Throw a runtime_error if attempting to divide
            // by zero
            throw runtime_error("Division by zero!");
        }
        // Perform the division and return the result
        return numerator / denominator;
    }
    catch (const exception& e) {
        cout << "Caught exception in divide(): " << e.what()
             << endl;
        // Rethrow the caught exception to handle it at a
        // higher level
        throw;
    }
}
  
// Function to calculate the sum of two numbers
int calculateSum(int a, int b)
{
    try {
        if (a < 0 || b < 0) {
            // Throw an invalid_argument exception for
            // negative numbers
            throw invalid_argument(
                "Negative numbers not allowed!");
        }
        // Calculate and return the sum
        return a + b;
    }
    catch (const exception& e) {
        cout << "Caught exception in calculateSum(): "
             << e.what() << endl;
        // Rethrow the caught exception to handle it at a
        // higher level
        throw;
    }
}
  
int main()
{
    try {
        // Calculate the sum of 10 and the result of
        // dividing 20 by 2
        int result = calculateSum(10, divide(20, 2));
        cout << "Result: " << result << endl;
  
        // Attempt to divide by zero, triggering an
        // exception
        int invalidResult = calculateSum(5, divide(10, 0));
        cout << "Invalid Result: " << invalidResult << endl;
    }
    catch (const exception& e) {
        cout << "Caught exception in main: " << e.what()
             << endl;
        // Handle the exception at the highest level
    }
  
    return 0;
}


Output

Result: 20
Caught exception in divide(): Division by zero!
Caught exception in main: Division by zero!

Explanation:

  • The program first calculates the sum of 10 and the result of dividing 20 by 2, which is 20. This result is printed and there are no exceptions raised in this part.
  • Next, the program attempts to divide by zero when calculating the sum of 5 and the result of dividing 10 by 0. This triggers a “Division by zero!” exception which is caught within the divide() function and rethrown. The rethrown exception is then caught in the main() function and is printed as “Division by zero!” along with the appropriate exception handling messages.

The Power of Rethrowing Exceptions

Rethrowing exceptions in C++ has the following advantages advantages:

1. Exception Type Preservation

The preservation of exception handling in C++ is a feature. It enables catch blocks at levels to effectively handle specific types of exceptions allowing for more precise error management.

2. Additional Processing

Additionally rethrowing exceptions provides the opportunity to perform operations or log extra information about the exception before it is caught again further up the call stack. For example you can add debugging details offer context or encapsulate the original exception within another exception to provide more helpful information to higher level catch blocks.

C++




try {
    // ...
}
catch (const exception& e) {
    // Perform additional operations or wrap the original
    // exception
    throw runtime_error("Additional information: "
                        + string(e.what()));
}


3. Catching Exceptions by Reference

When rethrowing an exception it is crucial to catch it by reference (const std;;exception&) rather than by value. This ensures that the exception object remains valid after being caught and rethrown multiple times during the exception handling process.

4. Handling Nested Exceptions

C++ also allows for nested exceptions where one exception is raised inside the catch block of another exception. If a nested exception is rethrown it becomes part of the exception as a std;;nested_exception. This feature enables handling of outer and nested exceptions if necessary.

C++




try {
    try {
        throw runtime_error("Nested exception");
    }
    catch (const exception& nested) {
        throw_with_nested(logic_error("Outer exception"));
    }
}
catch (const exception& outer) {
    // Handle the outer exception and potentially access the
    // nested exception
    try {
        rethrow_if_nested(outer);
    }
    catch (const exception& nested) {
        // Handle the nested exception
    }
}


5. Exception Propagation

Rethrowing exceptions allows them to propagate up the call stack until they are eventually caught and handled by a catch block. Any function in the call stack can halt the propagation of an exception by catching it and rethrowing it. This mechanism ensures that exceptions are handled based on the context in which they arise. In C++ rethrowing exceptions is an approach to effectively manage and handle them.

You can use exception handling in an controlled way to manage exceptions in your C++ programs. It gives you the ability to control how exceptions are handled preserve the types of exceptions perform processing and effectively handle nested exceptions. By understanding and utilizing the idea of exceptions you can write C++ programs that are more resilient and dependable.

Related Articles:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads