On tis, 2007-08-21 at 18:18 +0200, Erik Johansson wrote:
> In Licq 2 the plan is to use exceptions, at least internally within
> the daemon (to have or not have exceptions in the public api is
> another discussion). My question is how you think we should do it. Any
> best practices?
> 
> There are at least two ways to define exceptions:
> 1. A separate exception hierarchy, or
> 2. internal exception classes.

My vote is for a separate hierarchy. As exceptions can be thrown between
classes and may pass several functions before caught, they should be
declared "globaly" and not inside the class that threw it.

Also if exceptions will be used in the plugin api (which I think is a
good idea) they should be separate to let plugins (if they need it)
further add to the hierarchy internally.


> I think that 1 will give fewer and more general exception classes, but
> will mean more work when adding a new exception. 2 on the other hand
> makes it easy to add new exceptions so that you can add a
> BadPluginIdException and BadPointerArgException instead of just
> throwing BadArgumentException. Of course, the first two may inherit
> from BadArgumentException and give us a combination of 1 and 2.

Maybe we don't need exceptions for all subtypes of errors, a few general
exception classes might be enough if they have a parameter that specify
further information on what the specific error was.
For example, it is unlikely that any function will look at which
sub-exception of BadArgumentException it got and then try again with a
different value of that parameter. All it needs to know is that the call
failed, it will probably even be useless information that it was a
problem with the parameters. The fact that it failed is most likely to
be enough in most situations.


> The second question is, should we use throw-specifications when
> defining methods or simply document which exceptions are thrown?

throw() specification on functions looks better to me, that way the
compiler can also check if we throw something illegal.


> How should we handle low-level exceptions, such as out-of-memory?
> Simply ignore them since we're screwed anyway, or catch them as soon
> as possible and try to do something intelligent (what ever that is)?

I think std::exception should at least be caugh somewhere and tell the
user what happened and, if possible, do some kind of nice shutdown
rather than just crash. Stack traces are always nice to get in these
situations, in the error log if possible.
But anything causing bad_alloc or bad_cast to be thrown is probably
hopeless to recover from anyway so no need to add checks everywhere.
Otherwise we will just get a lot of meaningless catch(...) { cout << "we
got a problem here" << endl; }
"Don't look for an error condition you don't know how to handle."

/Anders

Reply via email to