
"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