Boost logo

Boost Users :

Subject: Re: [Boost-users] exception error_info list?
From: Emil Dotchevski (emildotchevski_at_[hidden])
Date: 2009-10-10 17:10:55


On Sat, Oct 10, 2009 at 6:06 AM, denis <mu_kuh_at_[hidden]> wrote:
> Emil Dotchevski wrote:
>> On Fri, Oct 9, 2009 at 5:48 PM, denis <mu_kuh_at_[hidden]> wrote:
>> > I would like to get all attached error infos from one exception.
>><snip>
>> > Then, everyone could implement his own version of
>> > diagnostic_information() without relying on boost internals.
>>
>> You do have some control over the output of diagnostic_information:
>> [...]
>
> Yes, but even if the output is not for end-users

You are right, this output is not for end users.

> For example I don't need the line "Throw in function (unknown)"
> (I rarely use BOOST_THROW_EXCEPTION) And I could use
> abi::__cxa_demangle to print a more readable name of an exception
> or error_info.

This is a good point, the "function (unknown)" should not be printed
if the function is unknown. Also, demangling the identifiers is on my
todo list.

Please don't get me wrong, I'm all for improving the output of
diagnostic_information. I'll accept any patches towards that goal.

>> > Beside that, I had another idea: When translating an exception it
>> > would be possible to copy all error_infos from the originating
>> > exception to the new one.  How do you handle this loss of
>> > information at the time?
>>
>> A copy of a boost::exception shares error_info ownership with the
>> original. Does this work for your use case?
>
> I don't think so. Where could I copy the exception in the
> following example, so that my_error() would have the error_infos
> from e?
>
>    struct my_error : public ex::exception {
>        virtual std::string
>        user_message () const {
>            // format() is just a little helper function in the base
>            // class using boost::get_error_info and boost::format
>            return format<boost::errinfo_file_name,
>                          boost::errinfo_errno>
>                ("The file %1% could not be read because %2%");
>        }
>    };
>
>    // -- snip --
>
>    try {
>        mylib::func(); // func throws with attached boost::errinfo_errno
>    } catch (mylib::system_error& e) {
>        throw my_error()
>            << e??
>            << boost::errinfo_file_name ("foo");
>    }

I don't know what ex::exception is but here's some code that copies
the error_infos from one exception to another:

struct exception_base: virtual boost::exception, virtual std::exception { };
struct exception1: exception_base { };

struct exception2: exception_base
{
    exception2(boost::exception const & e): boost::exception(e)
    {
    }
};

try { .... }
catch( exception1 & e )
{
    throw exception2(e);
}

Alternatively, you could use exception_ptr to store store the whole
"low level" exception (error_infos and all) as an error_info:

struct exception_base: virtual boost::exception, virtual std::exception { };
struct lib_exception: exception_base { };
struct app_exception: exception_base { };
typedef boost::error_info<struct
nested_exception_,boost::exception_ptr> nested_exception;

try { .... }
catch( lib_exception & e )
{
    throw app_exception() <<
        nested_exception(boost::current_exception());
}

(By the way, diagnostic_information will recurse into nested
exceptions and print the nested error_infos as well.)

Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net