Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to save an exception and throw it later

Tags:

c++

exception

Say I want to create an exception object, but throw it a bit later. My use case is that the exception is generated in a thread, but I need to actually throw it from my main thread (because there's nobody to catch it in the child thread)

using namespace std;

runtime_error *ex = nullptr;

thread myThread( [&ex]{
    if (something_went_wrong) {
        ex = new runtime_error("Something went wrong");
        return;
    }
} );

myThread.join();
if (ex != nullptr) {
    throw *ex;
}

For what it's worth, the compiler seems happy with this, but I can see that it's a resource leak at best. Is there a right way to do this?

like image 603
Edward Falk Avatar asked Nov 27 '25 04:11

Edward Falk


1 Answers

std::exception_ptr is the C++ facility to store exceptions. It can usually avoid an extra allocation.

std::exception_ptr ex = nullptr;

std::thread myThread( [&ex]{
    if (something_went_wrong) {
        ex = std::make_exception_ptr(std::runtime_error("Something went wrong"));
        return;
    }
} );

myThread.join();
if (ex != nullptr) {
    std::rethrow_exception(ex);
}

And since it can store any type of exception, you can store anything that could be thrown in the thread by wrapping the lambda like:

std::thread myThread( [&ex]{
    try {
        // do things
    } catch (...) {
        ex = std::current_exception();
    }
} );

Alternatively, you can use a std::optional<std::runtime_error>

std::optional<std::runtime_error> ex;

std::thread myThread( [&ex]{
    if (something_went_wrong) {
        ex.emplace("Something went wrong");
        return;
    }
} );

myThread.join();
if (ex) {
    throw *ex;
}

Which won't leak since you don't dynamically allocate

like image 176
Artyer Avatar answered Nov 29 '25 19:11

Artyer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!