Boost logo

Boost :

Subject: Re: [boost] [exception] Virtual inheritance with no default constructors
From: Adam Badura (abadura_at_[hidden])
Date: 2009-05-15 10:57:46


> On Wed, May 13, 2009 at 11:26 PM, Adam Badura <abadura_at_[hidden]> wrote:
>> Currently we can chain exceptions with boost::exception by constructing
>> a
>> new boost::exception and injecting to it error_info<struct
>> nested_exception_tag, exception_ptr> with exception taken by
>> current_exception. However at the catch site there is little we can do
>> with
>> exception_ptr without rethrowing it to catch it and print diagnostic
>> data.
>> How about allowing diagnostic data for exception_ptr?
>
> If you don't insist on the diagnostic message to be user-friendly,
> just use current_exception_diagnostic_information:

    That is not the same. With current_exception_diagnostic_information I
sure can achieve the desired result but in an ugly way which likely is also
inefficient and prone for failure due to another exception being thrown (for
example in low memory conditions).

    In cases I want to wrap just caught exception I inject it into exception
object to be thrown as exception_ptr data. This is something like:

typedef boost::error_info< struct Tag, boost::exception_ptr >
wrapped_exception_ptr;

void load_data()
{
    try
    {
        // Do internal staff.
        // Caller should not be interested in the details.
    }
    catch ( const implementation_specific_type& )
    {
        BOOST_THROW_EXCEPTION(
            load_data_error()
                // << inject some additional information as required
                << wrapped_exception_ptr( boost::current_exception() )
        );
    }
}

and then latter

try
{
    load_data()
}
catch ( const load_data_error& e )
{
    std::clog << boost::diagnostic_information( e );
}
catch ( ... )
{
    std::cerr << "Fatal error. Abort." << std::endl;
    std::abort();
}

    Note that this way, as I already described, while calling load_data I do
not have to bother what is its current implementation and what it might
throw. I know that it throws load_data_error if it fails but I can continue
(however without the data) or anything else in case of catastrophic errors.
(The examples might be more complicated.)
    However I do not loose even thinnest bit of information. Or rather I
wouldn't if boost::diagnostic_information was able to deal with error_info
of exception_ptr. But it does not. I could simulate this by asking the
exception object for wrapped_exception_ptr and if it returns one then
rethrowing that exception catching it and doing
current_exception_diagnostic_information for it. And likely doing it in loop
since the chain of exceptions may be longer.

    Adding function like

std::string to_string( const wrapped_exception_data& _e )
{
    try
    {
        boost::rethrow_exception( _e.value() );
    }
    catch ( ... )
    {
        return boost::current_exception_diagnostic_information();
    }
    return "to_string exiting unexpectedly";
}

helps a bit since boost::diagnostic_information will handle now
wrapped_exception_data and the "loop" for chained exceptions is achieved
automatically.
    However it still requires to throw and catch. And this does not seem
right.
    (Also note the return value at the end. I had to add it while compiling
on MS VS 2005 since is warned about not every control path returning a
value. Why rethrow_exception (and likely other similar functions as well) is
not marked as no-return? In case of MS VS 2005 it is done quite easy... But
if I am recalling well someone already asked for it.)

    If I am not mistaken it shouldn't be hard to allow
boost::diagnostic_information act on exception_ptr like on ordinary
exception.

    And yes. I know you are against chaining exceptions. However I showed
some use cases and you haven't showed any other solution to those (which
does not mean that non exists). Also note that simply copying data from one
exception to the other will not do as it might override some data (like the
basic ones: file name, line number and function name).

    Adam Badura


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk