This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of NAD status.

1132. JP-30: nested exceptions

Section: 17.9.8 [except.nested] Status: NAD Submitter: Seiji Hayashida Opened: 2009-06-01 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [except.nested].

View all issues with NAD status.

Discussion:

Addresses JP 30

C++0x nested_exception cannot handle a structured exception well. The following codes show two types of tree structured exception handling.

The first one is based on nested_exception in C++0x, while the second one is based on my library trickerr.h (in Japanese). http://tricklib.com/cxx/dagger/trickerr.h

Assume that Function A() calls two sub functions A_a() and A_b(), both might throw tree structured exceptions, and A_b() must be called even if A_a() throws an exception.

List A (code of tree structured exception handling based on nested_exception in C++0x)

void A()
{
    try
    {
        std::vector<exception_ptr> exception_list;
        try
        {
            // A_a() does a similar processing as A().
            A_a();
        }
        catch(...)
        {
            exception_list.push_back(current_exception());
        }

        // ***The processing A() has to do even when A_a() fails. ***
        try
        {
            // A_b() does a similar processing as A().
            A_b();
        }
        catch(...)
        {
            exception_list.push_back(current_exception());
        }
        if (!exception_list.empty())
        {
            throw exception_list;
        }
    }
    catch(...)
    {
        throw_with_nested(A_exception("someone error"));
    }
}
void print_tree_exception(exception_ptr e, const std::string & indent ="")
{
    const char * indent_unit = " ";
    const char * mark = "- ";
    try
    {
        rethow_exception(e);
    }
    catch(const std::vector<exception_ptr> e)
    {
        for(std::vector<exception_ptr>::const_iterator i = e.begin(); i!=e.end(); ++i)
        {
            print_tree_exception(i, indent);
        }
    }
    catch(const std::nested_exception  e)
    {
        print_tree_exception(evil_i(e), indent +indent_unit);
    }
    catch(const std::exception e)
    {
        std::cout << indent << mark << e.what() << std::endl;
    }
    catch(...)
    {
        std::cout << indent << mark << "unknown exception" << std::endl;
    }
}
int main(int, char * [])
{
    try
    {
        A();
    }
    catch()
    {
        print_tree_exception(current_exception());
    }
    return EXIT_SUCCESS;
}

List B ( code of tree structured exception handling based on trickerr.h. ) "trickerr.h" (in Japanese), refer to: http://tricklib.com/cxx/dagger/trickerr.h.

void A()
{
    tricklib::error_listener_type error_listener;
    // A_a() is like A(). A_a() can throw tree structured exception.
    A_a();

    // *** It must do process so that A_a() throws exception in A(). ***
    // A_b() is like A(). A_b() can throw tree structured exception.
    A_b();

    if (error_listener.has_error()) // You can write this "if block" in destructor
                                    //  of class derived from error_listener_type.
    {
        throw_error(new A_error("someone error",error_listener.listener_off().extract_pending_error()));
    }
}
void print_tree_error(const tricklib::error_type &a_error, const std::string & indent = "")
{
    const char * indent_unit = " ";
    const char * mark = "- ";

    tricklib::error_type error = a_error;
    while(error)
    {
        std::cout << indent << mark << error->message << std::endl;
        if (error->children)
        {
            print_tree_error(error->children, indent +indent_unit);
        }
        error = error->next;
    }
}
int main(int, char * [])
{
    tricklib::error_thread_power error_thread_power_on; // This object is necessary per thread.

    try
    {
        A();
    }
    catch(error_type error)
    {
        print_tree_error(error);
    }
    catch(...)
    {
        std::cout << "- unknown exception" << std::endl;
    }
    return EXIT_SUCCESS;
}

Prospect

We will focus on the method A() since the other methods, also main(), occur only once respectively.

According to the above observation, we cannot help concluding that it is not so easy to use the nested_exception handling as a tree structured exception handling mechanism in a practical sense.

This text is based on the web page below (in Japanese). http://d.hatena.ne.jp/wraith13/20081231/1230715424

[ 2009-10 Santa Cruz: ]

Mark as NAD. The committee agrees that nested_exception is not a good match for this usage model. The committee did not see a way of improving this within the timeframe allowed.

Proposed resolution: