Boost logo

Boost :

From: Pavel Vozenilek (pavel_vozenilek_at_[hidden])
Date: 2006-08-09 08:54:24


"Emil Dotchevski" wrote:

>>>>>>> http://article.gmane.org/gmane.comp.lib.boost.devel/146322
>>>>>
>>>> } catch(boost::exception& e) {
>>>> e.dump_everything(); // what happened?
>>>> }

> My point in this part of the discussion is that the fact that you could
> enumerate all the info in a boost::exception doesn't help you at all in
> formatting a meaningful user message, and is therefore just a debug
> feature.
>
Yes, that's exactly what I think.

> If you agree with this statement, then I think we should shift the
> discussion from "how do we enumerate all info in a boost::exception" to
> "how
> do we generate a complete (not necessarily user-friendly) debug string
> from
> a boost::exception".
>

Dump via lexical_cast.

Perhaps it may be implementable to have member
in exception_+info_value that does the dumping, like:

struct exc_tag_sqlite_error : boost::exception_info_value<int>
{
     void dump(ostream& os, int value) const {
          os << "a sqlite error is " << value << "\n";
     }
};

But even raw hex dump could be valuable.

_______________________________________________________
[ visitor-like approach vs individual catch statements ]
>> * Coupling.
>
> I see your point. You want to automatically translate between a set of
> (low
> level) exception classes, and another set of (high level) exception
> classes,
> while not really worrying about what info is contained in each exception.
> If
> this is the case, you don't need to visit all exception info stored in a
> boost::exception, you just want to be able to copy it without
> understanding
> it. Correct?
>

Yes for the (kind a) automatic translation between exceptions.

Just copying the old exception may not be sufficient:

   There are three entities involved: (1) lower layer,
   (2) higher layer and (3) exception handling in higher layer.

   The exception handler is a strange beast that may need
   rather deep knowledge of both lower layer
   (what really happened) and higher layer (what to do now).

   I draw an ASCII diagram, should look nice
  in Notepad or a text editor (A <--- B means B uses A):

------------- -------------------
high level <-- high level error
normal path transformer
------------- -------------------

     | |
     | |
     V V
------------- -------------------
low level <-- low level error
normal path generation
------------- -------------------

The normal-path code in higher layer could
be decoupled from exception handling
which (usually) depends on lower layer.

_______________________________________________________
>> * Isolation of error handling.
>
> Sure, but how do you handle an exception is quite different from how do
> you
> catch it. I think that dispatching between the different classes of
> failures
> should be done by catching different types of exceptions. Once an
> exception
> is caught, you can still have shared handling for multple exception types:
> just separate the shared code in a function, and call it.
>

Here I praise complete physical separation.
The ugly code dealing with errors and their
internal changes is out of sight and concentrated
on one place.

_______________________________________________________
>> * Safety: the correct ordering
>
> Finding bugs in exception handling code is very hard anyway. And a visitor
> could still be order-dependent, except that this dependency isn't as clear
> as the built-in order-dependency of C++ catch statements.
>
I believe ambiguities could be caught at compile time.

>> * If you add new exception or change
>> exception hierarchy you need to
>> update only the visitor class, not every
>> catch.
>
> I find myself repeating what I said earlier, but I think this is the
> essence
> of what you're trying to achieve with the "visitor" approach of hanling
> exceptions: you are replacing the "catch-by-type" semantics of C++ with
> "catch-everything-and-examine-its-value" semantics.
>

Replacing catch-by-type with the other:

    This is (welcomed) side-effect. My main argument
    is the ability to decouple normal-path and error-handling
    code into two independent (or less dependent) parts.

_______________________________________________________
Visitor also help with unit testing.
You may then manually construct lower layer exceptions
and pass them to the visitor and see what happens.

Advantages:
  * it is not necessary to invoke the actual error
    in lower layer (which may be impossible)
  * higher layer normal-path is not involved
    in such testing at all

This is not so easy with chain of catches.

/Pavel


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