Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to simulate inner exception in C++

Tags:

c++

exception

Basically I want to simulate .NET Exception.InnerException in C++. I want to catch exception from bottom layer and wrap it with another exception and throw again to upper layer. The problem here is I don't know how to wrap the catched exception inside another exception.

struct base_exception : public std::exception
{
    std::exception& InnerException;

    base_exception() : InnerException(???) { } // <---- what to initialize with
    base_exception(std::exception& innerException) : InnerException(innerException) { }
};

struct func1_exception : public base_exception 
{
    const char* what() const throw()
    {
        return "func1 exception";
    }
};

struct func2_exception : public base_exception
{
    const char* what() const throw()
    {
        return "func2 exception";
    }
};

void func2()
{
    throw func2_exception();
}

void func1()
{
    try
    {
        func2();
    }
    catch(std::exception& e)
    {
        throw func2_exception(e); // <--- is this correct? will the temporary object will be alive?
    }
}

int main(void)
{
    try
    {
        func1();
    }
    catch(base_exception& e)
    {
        std::cout << "Got exception" << std::endl;
        std::cout << e.what();
        std::cout << "InnerException" << std::endl;
        std::cout << e.InnerException.what(); // <---- how to make sure it has inner exception ?
    }
}

In the above code listing I am not sure how to initialize the "InnerException" member when there is no inner exception. Also I am not sure whether the temporary object that is thrown from func1 will survive even after func2 throw?

like image 443
Sivachandran Avatar asked May 14 '10 17:05

Sivachandran


2 Answers

Since C++ 11 you have new options:

  1. You can use std::exception_ptr.

    The exception is then preserve until last exception_ptr to this exception is destroyed.

    struct base_exception : public std::exception
    {
        std::exception_ptr InnerException;
    
        base_exception() {}
        base_exception(std::exception& innerException)
         : InnerException(std::make_exception_ptr(innerException))
        {}
    
    };
    
  2. Or you can simply use std::nested_exception.
like image 122
Vizor Avatar answered Sep 24 '22 00:09

Vizor


You should also take a look at boost exception for an alternative solution to wrapping.

like image 32
Hrvoje Prgeša Avatar answered Sep 23 '22 00:09

Hrvoje Prgeša