Boost logo

Boost :

Subject: Re: [boost] Boost and exceptions
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2012-06-24 01:08:29


On 06/23/2012 10:25 PM, Robert Ramey wrote:
> Steven Watanabe wrote:
>> I disagree. std::exception_ptr was primarily
>> designed to allow exceptions to be passed
>> between threads. The interface doesn't allow
>> you to do much besides rethrowing it unchanged.
>> Doing this means that the caller has
>> to catch someclass or my_unknown_exception
>> instead of boost::archive_exception.
>> It's true that using exception_ptr preserves
>> all the information from the original exception,
>> but it doesn't do it in a very convenient or
>> accessible way.
> hmmm - how do you believe that those who wrote the standard envisioned
> that this would be caught an handled?

I don't understand. I'm saying that what
you're trying to do is beyond the scope of
what exception_ptr was designed for. If
it could be used like this is would be great,
but AFAICT, it doesn't seem to work very well.

>> Even worse, if you use this in pre-existing code,
>> you've just introduced a breaking change, because
>> the type of the exception that comes out
>> is different.
> I'm not seeing this. If I throw a member of the class archive_exception,
> trap it in the above and rethrow it. Cannot I can catch it the
> same way I did here?

You can't, because the exception that
was rethrown is myclass, not archive_exception.

>> I don't see why that would be the case.
>> The point of using Boost.Exception is
>> to be able to add context information
>> to any exception as it goes by, not
>> to do any real error handling.
> I did this with "someclass" above. presumable the mechanics of "someclass"
> would be some part of boost exception. Then sometime higher
> one would catch someclass. since someclass copies the pointer
> there would be no slicing. This would be pretty much the
> same as boost exception as I understand it but not require
> any special code at the throw site.

Okay. Let's make this more concrete:

Consider code that looks like this:

void f(std::string filename) {
  // Use Boost.Serialization

void g() {
  try {
  catch(boost::archive_exception& e) { /*...*/ }
  catch(another_exception& e) { /*...*/ }

(This is very simplified. g doesn't have to
call f directly, and f doesn't have to use
Boost.Serialization directly.) Now, suppose
that we want to add the filename to the
exception in f. Using Boost.Exception:

void f(std::string filename) {
  try {
    // Use Boost.Serialization
  } catch(boost::exception& e) {
    e << archive_filename(filename);

Nothing else needs to change.

Using your approach:

void f(std::string filename) {
  try {
    // Use Boost.Serialization
  } catch(std::exception& e) {
    throw boost::exception(std::current_exception())
      << archive_filename(filename);

Now, g also has to change:

void g() {
  try {
  } catch(boost::exception& e) {
    bool caught = true;
    try {
    catch(boost::archive_exception& ae) { /*...*/ }
    catch(another_exception& ae) { /*...*/ }
    catch(...) { caught = false; }
    if (!caught)

The code has the same effect, but this
version of g is a lot harder to understand.

> The only substantive difference in functionality between the
> above and boost exception is that boost exceptiion
> requires creation of a wrapper at the throw site.
> I believe that boost exception functionality could be implemented
> without requiring this. This would be a far better and more robust
> solution and be much more useful when incorporating
> exisiting applications.

So, we've added one more element to the
list of possible problems. Pick your poison:

a) The exception gets sliced
b) All possible exception types are enumerated
   when we add any information to the exception
c) User code that handles the exception
   has to change and becomes really ugly

Do you have any more solutions to try?

In Christ,
Steven Watanabe

Boost list run by bdawes at, gregod at, cpdaniel at, john at