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.10.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.

- In the List A above (of the nested exception handling), it is hard to find out an active reason to use the nested exception handling at this scene. Rather, we can take a simpler description by throwing the entire exception_list directly to the top level.
- The code in the same example gives us a kind of redundant impression, which might have come from the fact that the try-throw-catch framework does not assume a tree structured exception handling.

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: