What if you need to catch an exception in a worker thread and re-throw it in the main thread that’s waiting for the worker to finish? std::future works this way. If you spawn a future on a new thread using std::async(std::launch::async, ...); and that future’s worker throws an exception, when you later call get() on the future it will emit that exception.
You do it by wrapping the worker thread’s function in try { /* CODE */ } catch(...) {} and capturing the current exception pointer ( std::exception_ptr) using std::current_exception. You can then re-throw the captured exception using the pointer and std::rethrow_exception. Below is an example that illustrates this technique. Just remember, if you have multiple worker threads make sure to have multiple std::exception_ptr instances; one per worker thread.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
#include <iostream> #include <sstream> #include <thread> #include <exception> #include <stdexcept> using namespace std; int main(int, char**) { exception_ptr ep = nullptr; thread t([&]() { try { stringstream str; str << this_thread::get_id(); throw runtime_error(str.str().c_str()); } catch(...) { ep = current_exception(); } }); t.join(); if(ep != nullptr) { try { rethrow_exception(ep); } catch(exception& e) { cout << "Thread " << this_thread::get_id() << " caught exception from thread " << e.what() << endl; } } } |
Thread 0x1048d75c0 caught exception from thread 0x700001cf3000
Program output.