
John Maddock wrote:
Why does the serialization library have to include code from boost exception in order to do this?
You can use boost exception at the same place, catch the standard exception that the serialization throws, construct you're own boost exception and continue on.
No!!!!
Misses the whole point - Boost.Exception allow you to annotate an existing exception without loosing the original information - and that includes the *type* of the original exception.
Here is what I don't get. When the serialization code was written I decided that the exception mechanism was that right way to go. I realized that just a "generic" exeception wouldn't included enough information so I created boost::archive::exception and extra data specific the this kind of acception. The file name is archive_exception.hpp. This exception type has most of the useful information regarding the exception. Some was excluded as it would make the type "heavier" than I wanted or would have required data types which might use the heap or other resources which of course would be a disaster. It also was carefully designed not to include RTTI and other stuff which would make the library less attractive for lighter weight applications. Basically this was designed as the best balance among all the considerations I had to take into account - including the desire to pass as much information as possible to the application. I also used boost::throw_exception in order to permit the system to gracefully handle the case where exception were either not available or not permited in the user environment. boost::throw_exception was explicilty designed for this purpose and no other. So - boost::throw_except is changed and.... what? I already included all the useful information I can add. How can boost::throw_exception add to this on it's own? What can it possible do that's useful? The archive_exception is already derived from the standard base class so it can be caught by catch(std::exception e &). It's derived virtually from std::exception so the e in can be downcast to the archive_exception and get all it's data. If the user want's to, he has the option or using rtti type_id to get the type - but he's not forced to if he want's to keep his code lean and mean. To summarize, I don't see how just changing boost::throw_exception without changing anything else can possible add anything useful to the library or the users application.
Consider writing a future - in order to preserve all the exception information, you would have to be able to catch, clone, and then rethrow *every possible exception type* that may be thrown by the code that the future calls. It is quite simply impossible.
However, if all thrown exceptions inherit from boost::exception, then you simply catch that exception type, ask it to clone itself, and rethrow in a different thread. You preserve all the original error information, and crucially, all the original type information, even though the future doesn't itself know what the actual dynamic type of the caught and rethrown exception is.
Hmmm - I don't see how just changing the implementation of boost::throw_exception would change this in anyway. Perhaps you're suggesting that in addition to chaning the functionality of boost::throw the serialization libary should redefine archive_exception to derive from boost::exception rather directly from std::exception. Of course that's a totally different topic than we've been discussing up until now. and I guess would be a new thread. But maybe you're not suggesting that. Sorry if I got this wrong. Still, you're question obligated me to think a little about this. I would expect a library such as boost exception would have code along the following lines somewhere to be included/invoked from user code. void * x x = dynamic_cast<boost::exception be *>(std::current_exception()) if(0 != x){ ... // do great boost exception stuff } else { void * x = dynamic_cast<std::exception be *>(std::current_exception()); .. // use what() and do some stuff } else{ // handle the case where the library, user didn't bother to use std::exception } But this is totally compatible with the original implementation of boost::throw_exception! So it looks to me that changing the functionality of boost::throw adds nothing to libraries which don't use boost::exception. Even if libraries are changed to use THROW_BOOST_EXCEPTION the only thing added is file # / line # - I havn't heard any users clamoring for that. Finally, any users who want real information on the exception will have to include archive_exception.hpp in any case. True it make users think they are "handling" something - but if there's not catching archive_exception and dealing with the specifics, they might as well use std::exception. So I don't see that boost exception actually adds anything of any value.
This actually looks compelling enough to me, that we should probably mandate use of BOOST_THROW_EXCEPTION.
lol - right.
My complaint is the process by which it was inject. Fair enough, but you're still 4 years too late on that one.
lol - well I wasn't late when I brought it up the first time. It was right at release time when this bomb was dropped in at the last moment.
I repeat an earlier question - if Boost.Exception were refactored to put the "core" exception throwing code either into boost/detail/ or indeed directly into boost/exception.hpp given that there's not much of it, would that address at least some of your concerns?
I don't get this. Wouldn't this still drag in hundreds of lines of code that aren't being used?
BUT - now you've sucked me into looking at the merits of including it, I don't see that it would be of any use. here's typical serialization code:
#include <boost/archiive/binary_iarchive.hpp> #include <ifstream> ... f(...){ ifsteam is("my file") binary_iarchive ia(is); try { my_data d; ia >> d; } catch(boost::archive::exception ae){ std::cout << ae.what(); throw(ae) ; // or throw something else } return; }
So if I want to use boost exception I would just write
#include <boost/archiive/binary_iarchive.hpp> #include <ifstream> #include <boost/exception/???.hpp> ...
f(...){ ifsteam is("my file") binary_iarchive ia(is); try { my_data d; ia >> d; } catch(boost::archive::exception ae){ std::cout << ae.what(); // I don't know how to use boost::exception insert your own code here boost::exception::throw(?) } return; }
I don't see injecting boost::exception into the serialization code changes this in any way
Please see my answers above.
I still don't see how boost exception helps in my example. If you don't care about handling archive_exception you can just use ifsteam is("my file") binary_iarchive ia(is); my_data d; ia >> d; and just handle std::exception upstream. If you really like boost::exception your code when you eventually can eventually rethrow catch (std::exception e){ BOOST_EXCEPTION_THROW_EXCEPTION(e) }
Now consider that the serialization code includes some use of Boost.Filesystem, Boost.Regex (filename parsing) and heaven known whatever other dependencies the object being [de]serialized depends on (presumably an object being deserialised could throw any exception Boost is capable of). If all those exception objects uniformly derive from boost::exception somewhere in their object hierarchy, then you catch *one* exception type, annotate it, and rethrow. All the original type information is retained, clients can catch the boost::exception and enumerate all the information it holds, or they can catch something more specific like boost::archive::exception and work from there.
How is this different from using std::exception ?
I admit to being new to what boost::exception has to offer, but that looks pretty compelling to me,
Sorry john, I'm still not seeing it. You'll have to dumb it down for us mortals. Robert Ramey
Cheers, John.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost