On 2/1/11 4:31 PM, Stephen Williams wrote:
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.

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.
    * At key API layer boundaries, map all internal / low level exceptions to 
classes of exceptions: memory, math, bad parameters,
      ...  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.
    * Use exception hierarchies to group types when 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.
    * 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.
    * 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.


Stephen

On 2/1/11 3:27 PM, Gary Gregory wrote:
-----Original Message-----
From: Gilles Sadowski [mailto:gil...@harfang.homelinux.org]
Sent: Tuesday, February 01, 2011 18:16
To:dev@commons.apache.org
Subject: Re: [all][math] Help wanted with exceptions API design

The currently defined exceptions in [math] can be found in the
top-level package and .exceptions.  Those in the top-level have at
this point been deprecated.
Don't package your exceptions in a package called ".exceptions". That is
very odd.

Why?

The exception should be defined where they are used.
What do you do for exceptions that are used in several classes and several
packages?
Here is a probably too simple example:

com.example defines IOException
com.example.input uses IOException
com.example.output uses IOException

As I and others have suggested: reuse existing stock exceptions. Only
create exceptions classes if you must.

Depending on the requirements, the exceptions we created may be more
convenient.

If you consider creating an exception, especially in a hierarchy, think:
why would I want to CATCH this exception as opposed to a superclass?

I don't agree because I don't consider from that stand-point. IMHO, the
exception is useful if it conveys a problem as specifically as possible.
The caller is free to catch, or not, whatever he likes.


Best,
Gilles

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


--
Stephen D. Williams s...@lig.net stephendwilli...@gmail.com LinkedIn: http://sdw.st/in V:650-450-UNIX (8649) V:866.SDW.UNIX V:703.371.9362 F:703.995.0407 AIM:sdw Skype:StephenDWilliams Yahoo:sdwlignet Resume: http://sdw.st/gres Personal: http://sdw.st facebook.com/sdwlig twitter.com/scienteer


--
Stephen D. Williams s...@lig.net stephendwilli...@gmail.com LinkedIn: http://sdw.st/in V:650-450-UNIX (8649) V:866.SDW.UNIX V:703.371.9362 F:703.995.0407 AIM:sdw Skype:StephenDWilliams Yahoo:sdwlignet Resume: http://sdw.st/gres Personal: http://sdw.st facebook.com/sdwlig twitter.com/scienteer

Reply via email to