Propagating Nested Exceptions Across Threads
Can I throw a nested exception from one thread and catch it in another thread?
Yes, you can propagate nested exceptions across threads, with some caveats.
In C++11 and later, if a function called by std::thread
exits with an uncaught exception, the runtime captures that exception and stores it. When you call join()
or get()
on the std::thread
or std::future
object, it will rethrow that stored exception.
This works with nested exceptions too. If the thread function exits with an uncaught nested exception, it will be captured and rethrown when join()
or get()
is called.
For example:
#include <exception>
#include <iostream>
#include <thread>
void thread_func() {
try {
throw std::runtime_error{"Inner Exception"};
} catch (...) {
std::throw_with_nested(
std::logic_error{"Outer Exception"});
}
}
void join_thread() {
try {
std::thread t{thread_func};
t.join();
} catch (const std::exception& e) {
std::cout << "Caught exception: " << e.what() << '\n';
// Rethrow the std::runtime_error if desired
// std::rethrow_if_nested(e);
}
}
However, there are some limitations:
- The exception types must be copyable, because the exception is copied into the
std::thread
orstd::future
object. - If the thread function exits via other means (e.g., by calling
std::terminate
), the behavior is undefined. - If the
std::thread
orstd::future
object is destroyed without callingjoin()
orget()
, the stored exception is lost andstd::terminate
is called.
So while you can propagate nested exceptions across threads, it's important to handle and rethrow them properly to avoid unexpected behavior.
Nested Exceptions
Learn about nested exceptions in C++: from basic concepts to advanced handling techniques