>On Fri, January 19, 2007 22:33, Trigve Siver wrote: > >(Note: I've rearranged the ordering of this message to Internet-style >quoting for clarity: oldest message first, with one level of quote marks >added per step in the thread) > >>> From: Marcel Loose <loose at astron.nl> >>> Sent: Friday, January 19, 2007 4:22:30 PM > >>> The problem I'm facing is that pqxx has four different top-level >>> exception classes (broken_connection, sql_error, in_double_error, and >>> internal_error). In order to not let any of those exceptions leak out, >>> I'll have to write a try/catch with 4 different catch blocks for each >>> call that may throw. This causes a lot of code duplication. >>> Wouldn't it be a better idea to have one exception base class (e.g. >>> pqxx::base_exception) and derive the other pqxx exceptions from >>> base_exception, instead of deriving them form std::runtime_error and >>> std::logic_error? > >> I think that all exceptions are derived from std::exception...so u can use >> catch with std::exception > >Well yes, but that's not going to make it easier for him to separate the >libpqxx-specific exceptions from things like out-of-memory errors. > >I don't think it would make sense to discontinue use of the standard >exception hierarchy either: the whole point of libpqxx is to fit in with >the standards set by the C++ standard library. > >So how about multiple inheritance? We could have a base "pqxx_exception" >class. Then, for instance, pqxx::sql_error would still inherit >std::runtime_error but also, through multiple inheritance, >pqxx::pqxx_exception. > >If we did that, the program could "catch (const pqxx::pqxx_exception &)" >first to filter out all pqxx-specific exceptions. A later clause could, >for example, "catch (const std::runtime_error &)" to catch all *other* >runtime_errors. > >Of course you'd have to be careful to avoid slicing (that happens if you >catch a base exception class by value instead of by reference, and a >derived-class exception is thrown) but that was already the case anyway. > > >Jeroen
Hmm, for some weird reason I did not get this message by email, so I copied/pasted it from the web page. Jeroen, I would think twice before walking the path of multiple inheritance. This will sooner or later cause disaster, especially because your exception classes keep state (i.e. have data members). I understand you're willing to adhere to the C++ standard hierarchy. The thing is that the interpretation of what represents a logic_error and what a runtime_error depends on point of view. In my opinion, determining whether an error is a logic_error or a runtime_error depends on whether all preconditions were met or not. If any precondition is violated, it is a logic_error, otherwise a runtime_error. Hence, it depends on what preconditions you impose. For example, is it a logic_error or a runtime_error if a programmer tries to call a non-existing stored procedure? Well, it depends. If the list of stored procedures is fixed and properly documented, you may argue that it is a logic_error to call a non-existing stored procedure (violation of precondition). On the other hand, if the list is not fixed and/or not properly documented, it would probably be better to call it a runtime_error. That's why some people consider the current C++ exception hierarchy not (well, eh) optimal. Personlly, I prefer to derive my own exception class hierarchy directly from std::exception (I don't use any of the derived standard exception classes), so that I avoid falling into this snake pit. Just my two cents. Regards and keep up the good work. Marcel Loose. _______________________________________________ Libpqxx-general mailing list [email protected] http://gborg.postgresql.org/mailman/listinfo/libpqxx-general
