Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use throw_with_nested and catch nested exception

I really like std::throw_with_nested in c++11 since it emulates java's printStackTrace() but right now I am just curious how to catch a nested exception, for example:

void f() {
    try {
        throw SomeException();
    } catch( ... ) {
        std::throw_with_nested( std::runtime_error( "Inside f()" ) );
    }
}
void g() {
    try {
        f();
    } catch( SomeException & e ) { // I want to catch SomeException here, not std::runtime_error, :(
        // do something
    }
}

Previously, I thought std::throw_with_nested generates a new exception which is multiply derived from two exceptions (std::runtime_error and SomeException) but after reading some online tutorial, it encapsulates SomeException within std::exception_ptr and it's probabaly why I canonot catch it.

Then I realized I can fix this by using std::rethrow_if_nested( e ) but the above case is only two level which is easy to handle but thinking about more general situation like 10 level folded and I just don't want to write std::rethrow_if_nested 10 times to handle it.

Any suggestions would be really appreciated.

like image 532
Tangent Ksai Avatar asked Aug 07 '13 16:08

Tangent Ksai


1 Answers

Unwrapping a std::nested_exception is readily accomplished via recursion:

template<typename E>
void rethrow_unwrapped(const E& e)
{
    try {
        std::rethrow_if_nested(e);
    } catch(const std::nested_exception& e) {
        rethrow_unwrapped(e);
    } catch(...) {
        throw;
    }
}

Where usage would look something like this:

try {
    throws();
} catch(const std::exception& e) {
    try {
        rethrow_unwrapped(e);
    } catch (const SomeException& e) {
        // do something
    }
}

A demo of this in action can be found here.

like image 132
tclamb Avatar answered Sep 29 '22 06:09

tclamb