Hi.

> >I know I've recently seen a great example of a library that
> >started with generic exception classes then later changed to a
> >specific hierarchy.  But I can't remember off hand which library
> >it was...
> >
> >There is some low level where you just want to get back the raw
> >exception, null pointers etc. when they are unexpected.  For
> >debugging, even for an app running in the field, you want code
> >that can capture the problem to get the actual exception, be able
> >to get a stack trace, etc.  When an exception is expected, as in a
> >parameter that is null to signal that it is not wanted for
> >instance, that should be caught, interpreted, and turned into an
> >exception that has a specific meaning.  In a lot of ways, it seems
> >like the arguments for semantic web ontologies apply here in terms
> >of assigning meaning to events.
> >
> >In larger apps, what I've found is that a hierarchy of exceptions
> >is useful to A) simply code that needs to make decisions (IO
> >error? Network?  Math?  Out of memory?) while B) other code needs
> >details (exact exception, stack trace, transaction#s, etc.) to
> >give detailed messages, support debugging, etc.

In the case of Commons Math, my view is that its component don't have to
make decisions (mostly) and must let the caller deal with the exception.
We are in your (B) case.

> >If exceptions are generic to everything at a certain level, then
> >it should be shared.  If it is specific because something relevant
> >needs to be returned, say a particular line item in a transaction,
> >it should be specific to the application rather than the error.
> >It can carry the more specific to the failure exception.
> >
> >Here are my rules, so far.  Please comment as I plan to write up a summary 
> >for myself later.
> >
> >    * Don't hide or lose information potentially important for debugging or 
> > application decisions.

Agreed.

> >    * At key API layer boundaries, map all internal / low level exceptions 
> > to classes of exceptions: memory, math, bad parameters,

Hmm. What is low-level vs high-level vary with the code at hand. [E.g. for a
spread-sheet application a math exception might be considered low-level
while for Commons Math it is high-level.]

I agree that the exception must be "understandable" at the level where it is
caught (that's the point for the mapping at API boundary).
One of the issues we are having is: Which side of the boundary should do the
mapping. I contend that the caller (i.e. the upper side of the boundary) is
responsible for this mapping because it knows the context of the call and
whether it will make sense, or not, to let propagate the exceptions
potentially thrown by the call it is going to make.

> >      ...  Except that truly unexpected exceptions can be left to be caught 
> > in many cases.  Catching and converting all of those
> >      can make debugging much harder unless stack traces are kept.

That's what I do the most (because in my code most exceptions come from
bugs).

> >    * Use exception hierarchies to group types when possible.

Agreed.
When is it not possible?

> >    * Think carefully about checked vs. unchecked exceptions.  There is a 
> > particular idiom I like that makes using checked
> >      exceptions ugly: In some cases, say a map/xml get method, you can 
> > simply code by passing in what to do if the value is not
> >      found.  Ideally, you want to pass alternatives like: null, "", 
> > "empty", or MyException.  Unfortunately, if a method could
> >      return a checked exception, it must always be caught, even if a 
> > particular call will never do so.  In this case, an
> >      unchecked (i.e. not required to be caught) exception should be used, 
> > always checked by convention.

The cases when to use checked vs unchecked has been very clearly explained
in J. Bloch's book.
[Basically, if you cannot recover from the failure signalled by the
exception, it must be unchecked.]

> >    * High-level concept exceptions should be defined and used to improve 
> > documentation.  For example, "OutOfStock" would be a
> >      reasonable exception for a 'purchase("chair")' method.

I agree but some cases are not as easy to decide on :-).
[It could be that the "chair" item is not on sale in this particular shop...]

> >    * Class-specific, high-level exceptions should be declared as inner 
> > classes of the class that throws them.  This is an
> >      application of a more general rule on when to use inner
> >classes to avoid class space pollution, aka "class diarrhea".
> >Defining compound or special return types, or alternatively
> >callback signatures, as inner classes is often better also.  I
> >      think of it as being object oriented at the next level up of 
> > granularity.

I think that you are mixing up things here.
Avoiding space pollution is nice. But one exception class is supposed to
describe one (bad) condition, and should be reused everywhere (in other
classes and in other packages) that failure happens. So in this case, inner
classes are not appropriate.


Best,
Gilles

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org

Reply via email to