Boost logo

Boost Users :

Subject: Re: [Boost-users] exception: use of error_info can mask real exceptions
From: Emil Dotchevski (emildotchevski_at_[hidden])
Date: 2009-05-25 02:40:29

On Sun, May 24, 2009 at 11:02 PM, Andrew Venikov
<andrew.venikov_at_[hidden]> wrote:

Slightly more specific example:

typedef boost::error_info<struct tag,int> info1;
throw foo() << info1(bar());

I understand that if in the above code bar() throws, you still want
foo propagated. Now, a slight change:

int x=bar();
throw foo() << info1(x);

What behavior do you want in case bar() throws?

>>> When I write this:
>>> throw WidgetAllocError();
>>> It's pretty obvious what I want.
>>> Of course, it would be nice to have more informative description, that's
>>> why I would normally add:
>>> throw WidgetAllocError() << WidgetErrorDescription(strWidgetName);
>>> But this now changes the original intent. By the time we reach the throw
>>> statement, we've made a decision that an error condition has been
>>> reached and we want to indicate that error. If we continue propagating
>>> WidgetAllocError(), then we'll at least know what kind of error
>>> happened, albeit without extra information.
>> That "albeit" is very important. It effectively requires the catch
>> site to be able to deal with a WidgetAllocError that has no additional
>> information in it. Are you sure you want to impose this requirement on
>> all programs wrt all exceptions?
> Agreed.
> But if I understand correctly, even now the good style to catch
> error_info is first to call get_error_info(), and then check the pointer for
> null.

This has nothing to do with style. The following program is valid:

#include <boost/exception.hpp>
#include <iostream>

struct foo: virtual std::exception, virtual boost::exception { };
typedef boost::error_info<struct tag,int> my_info;

    throw foo() << my_info(42);
  catch( foo & e )
    std::cerr << *boost::get_error_info<my_info>(e);

> It looks like we really have to decide, what's more important -
> preserving the original exception or preserving a newer exception.

No, the decision is between ignoring the failure to throw an exception
with specific error info in it or not ignoring it.

By the way, if you want to ensure that throw foo() will necessarily
throw foo, that's not possible. Throwing an exception requires memory,
and if that memory is not available, throwing std::bad_alloc instead
is allowed behavior (the implementation is required to always be able
to throw std::bad_alloc.)

Emil Dotchevski
Reverge Studios, Inc.

Boost-users list run by williamkempf at, kalb at, bjorn.karlsson at, gregod at, wekempf at