Exception design question was Re: Interface design problem
On Tue, 26 Aug 2008, Martin Gregorie wrote:
On Tue, 26 Aug 2008 12:29:58 +0100, Tom Anderson wrote:
On Tue, 26 Aug 2008, Martin Gregorie wrote:
On Tue, 26 Aug 2008 09:46:03 +0100, Tom Anderson wrote:
If you're feeling like overcomplicating things, you could define a
new FileSystemException, and have subclasses for the various kinds of
failure - FileNotFoundException, RemoteCommunicationException, etc.
Why subclass it? Couldn't you achieve the same thing by adding an
exceptionCategory attribute and corresponding getter to
FileSystemException?
What, you mean like Sun could have just had one Exception class (well,
one Exception, one Error, and one RuntimeException) and just had an
exceptionCategory attribute?
No, I'm not suggesting that.
Okay. Apologies for the sarcasm.
However, I've seen some standard exceptions (ClassNotFoundException,
SQLException) that carry extra information and implement methods to
access it. ClassNotFoundException, in particular, looks as if it could
have been subclassed instead.
What extra information does ClassNotFoundException have? AFAICT, it just
has a message and a cause.
In this case it might be more convenient to add extra fields to carry
essential stuff from the underlying Exception rather than subclassing
it. I'm wondering what, apart from personal preference, determines which
of the two approaches should be used in a given situation.
That's a really good question. Anyone like to propose an answer?
My personal preference is for lots of subclassing, so that information
about the exception is encoded in an easily usable way in its type - you
can filter out specific exceptions with specific catch clauses, rather
than having to do catch-check-handle-or-rethrow, and the nature of the
exception is immediately apparent from its class name. However, if there
is some kind of property that's meaningful over a range of exception
types, then that should certainly be made accessible, through a getter
defined in a common base class.
For instance, you could (*could*) break SQLException into subclasses along
SQLState lines: you'd have SQLException, then subclasses NoDataException
(for 02000), DynamicSQLException (for 07xxx), ConnectionException (for
08xxx), etc. NoDataException would be concrete, but 07 has subcodes, so it
would be abstract, with concrete classes for
WrongNumberOfVariablesException (07001), InvalidParameterListException
(07002), etc. However, you'd still want to have an int getSQLState()
method in SQLException, so you could get the code directly if you wanted.
Note that i'm not seriously suggesting that SQLException should be done
this way: that really seems over the top. I guess my test is "are these
two kinds of exception different enough that calling code might want to
deal with them differently?"; if they are, use subclasses, so that
separate catch clauses can be written. If they aren't, capture the details
in a field, so it can be reported.
In the OP's situation, i think network errors and files not being found
probably would be handled differently. You might want to automatically
retry in the case of a network error, possibly after rebooting the
connection; you probably wouldn't want to do that for a file not being
found. You'd certainly want quite different error messages.
tom
--
First man to add a mixer get a shoeing! -- The Laird