From: "Beman Dawes" <[EMAIL PROTECTED]> > Boost libraries often define exception classes, usually derived from the > standard library exception hierarchy. Users sometimes ask for further > refinement, so the library ends up with its own hierarchy. > > For example, the Filesystem library started out with > boost::filesystem::filesystem_error, but reviewers asked for more specific > exceptions at least for the most common errors (like "file not found".) The > suggested plan was to add one or two derived error types now, and more as > experience dictates.
I don't have filesystem_error handy as I write this but from what I remember, it was impossible to handle a filesystem_error in a portable manner, for any nontrivial definition of "handle". The only information it provides is an implementation-defined error code and an implementation-defined explanatory message. The former cannot be used portably to affect code flow; the latter, in the general case, cannot be presented to the user. Sorry if this sounds too harsh, but the only goal of the Filesystem library is to provide a _portable layer_; hence, the library _must_ report errors in a portable manner. My suggestion is to adopt errno codes as a way of portably identifying the error, and return the string representation of the corresponding macro from what() (i.e. ENOMEM, EACCES, ENOTDIR.) In other words, filesystem exceptions should probably derive from namespace boost { class errno_exception { public: virtual char const * what() throw(); int error() const; }; } (errno_exception comes in handy when one needs to report pthread failure or other POSIX failures, too) although other solutions are possible. Note that the above is a good counterexample for the suggestion that what() should return typeid().name(). > That works well for callers who know exactly what exception types will be > thrown, but also implies that libraries like Boost.Test which try to catch > specific exception types (for better error reporting) have to be > continually updated to reflect new boost exceptions being added. An > exception class which was self-explanatory would be better for these uses. > I try to cope with that need by a lengthy what() message. Libraries that only need to report the error should not need to catch specific types. The only reason for the current (sad) situation is that the what() string is not well defined, and hence, unreliable. It is common knowledge that the what() string of the exceptions thrown by standard library implementations is close to completely useless. > In another thread, Peter Dimov has pointed out that providing a what() > message that can be used as a key is helpful in internationalizing > messages. You can replace "helpful" by "required". The alternatives, from software design perspective, are inferior. > Has anyone run into a comprehensive attack on these and similar exception > class problems? Is there a better way than each Boost developer just > hacking together individual exception classes? Could we do better with a > Boost exception class or idiom? std::exception, if used correctly, can solve these problems. One problem with defining a separate exception hierarchy is that sometimes it's useful to choose std::logic_error, or std::runtime_error, as a base class. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost