|
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