> Solution 1: declare a brand new Exception that encanpsulates the inner
> ones.
> void loadChildren(Node node) throws ChildrenLoadingException {
> What can you suggest me about solution 1, 2 or 3?
Use solution 1 ... throw new ChildrenLoadingException(detailMessage,
originalException) (punts to the Exception(String, Exception) constructor).
> Suppose that the an implementation of
> ChildrenLoadingStrategy.loadChildren() contains SQL code. And
[quoted text clipped - 3 lines]
> IOExceptions.
> How do i reflect these exceptions in the Node.getChildren() method?
To answer this question, think about the design of your code:
1. What does an SQLException or IOException mean in your case? Is it:
a. User validation error? (Notifying the GUI and refusing to
continue is the best option here)
b. An expected event? (Rewriting it so it isn't expected is the best
option here)
c. A recoverable error? (Propagating a checked exception is best here).
d. A fatal error? (Dieing and logging the error is best here).
> Solution 1: declare a brand new Exception that encanpsulates the inner
> ones.
[quoted text clipped - 9 lines]
> ChildrenLoadingException {...}
> Comment: Do you like it? i don't. Somehow it "stinks"
This is the preferred method of recovery, but it generally helps to keep
these propagating errors as close to the point of failure as possible.
> Solution 2: declare ANY Exception
> void loadChildren(Node node) throws Exception {...}
> public List<Node> getChildren() throws Exception {...}
> public List<Node> anyOtherMethodInNodeThatCallsGetChildren() throws
> Exception {...}
> Comment: mmmmm.
Horrible and defeats the purpose of checked exceptions.
> Solution 3: say goodbye to checked exceptions
> void loadChildren(Node node) {
[quoted text clipped - 7 lines]
> public List<Node> anyOtherMethodInNodeThatCallsGetChildren() {...}
> Comment: Terrific! Or maybe better than solution 2?
Even worse than solution 2, by far the worst of all: by the points at
which you start handling recovery, it can become impossible to handle
developer bugs (which are those that tend to subclass RuntimeException:
ArrayIndexOutOfBoundsException, etc.) from real bugs that need error
handling.
> What can you suggest me about solution 1, 2 or 3?
Pick solution 1. Purge solutions 2 and 3 from your mind immediately.
They should not be used in any production code.

Signature
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth
Joshua Cranmer - 22 Sep 2007 16:40 GMT
>> What can you suggest me about solution 1, 2 or 3?
>
> Pick solution 1. Purge solutions 2 and 3 from your mind immediately.
> They should not be used in any production code.
(Hit "Send" too quickly)
Java has, IMO, the best error-handling exception system out there. [*]
The notion of checked exceptions is perhaps its best feature--it forces
developers to actually properly handle errors where they might blithely
be ignored. In addition, checked exceptions makes the documentation of
errors a lot easer (quick: what error does Python throw if it tries to
read from a file that is on an NFS share that has been unmounted?).
[*] Well, some of the implementation is poor: the close() method of an
IO stream can throw an IOException, which makes handling resource clean
up painful.

Signature
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth
Mike Schilling - 23 Sep 2007 10:12 GMT
>>> What can you suggest me about solution 1, 2 or 3?
>>
[quoted text clipped - 13 lines]
> stream can throw an IOException, which makes handling resource clean up
> painful.
It's a bit useless for InputStream.close() to throw an exception; if you're
done reading from the stream, you presumably don't care that you, say, lost
contact with an NFS mount. But if an OutputStream has been buffering output
that close() can't flush properly, how would you prefer to be notified of
that?
>How do i reflect these exceptions in the Node.getChildren() method?
Probably the easiest way to handle this when you don't know what sort
of mess the implementor might throw is to make up a new Exception, and
have the implementor catch any miscellaneous exceptions and wrap them
in the new standard catch-all Exception and rethrow that.

Signature
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
Lew - 22 Sep 2007 20:53 GMT
ennioennioennio@gmail.com wrote,
>> How do i reflect these exceptions in the Node.getChildren() method?
> Probably the easiest way to handle this when you don't know what sort
> of mess the implementor might throw is to make up a new Exception, and
> have the implementor catch any miscellaneous exceptions and wrap them
> in the new standard catch-all Exception and rethrow that.
Good advice, and to wrap them use the idiom that Ben Phillips explained:
> Use solution 1 ...
> throw new ChildrenLoadingException(detailMessage, originalException)
> (punts to the Exception(String, Exception) constructor).
I repeat it because it's such good advice, and because it provides a detail
for the implementation of Roedy's advice. All the answers in this thread
coordinate with each other:
Joshua Cranmer:
> think about the design of your code:
> 1. What does an SQLException or IOException mean in your case?
and
> The notion of checked exceptions ...
> ... forces developers to actually properly handle errors
> where they might blithely be ignored. In addition,
> checked exceptions makes the documentation of errors a lot easier
The unifying notion is that checked exceptions are an API signature mechanism
to provide meaningful error recovery to client invocations.
The checked exception should have meaning appropriate to the component or
system layer that (re)throws it. For example, a Data Access Object
(DAO)-layer class likely would receive IOExceptions, particularly
SQLExceptions from the APIs it invokes. Those exceptions have meaning to it,
because a DAO "knows" about such things. What it throws is a "Data Access"
problem to upstream clients - perhaps derived from IOException but certainly
in its own, application-specific domain of discourse. Thus one would rethrow
new DataAccessException( "domain-meaningful message", ioExcFromDownstream )
as Ben showed.
Good encapsulation has the exception carry meaning in terms the invoker
understands, not what goes on under the API's covers.

Signature
Lew
Roedy Green - 22 Sep 2007 21:39 GMT
On Sat, 22 Sep 2007 19:37:27 GMT, Roedy Green
<see_website@mindprod.com.invalid> wrote, quoted or indirectly quoted
someone who said :
>Probably the easiest way to handle this when you don't know what sort
>of mess the implementor might throw is to make up a new Exception, and
>have the implementor catch any miscellaneous exceptions and wrap them
>in the new standard catch-all Exception and rethrow that.
I should refine that advice. If you have a non-trivial interface, you
probably should devise a set of Exceptions (all derived from the same
root) that define what went wrong in terms that make sense relative to
the services offered by the interface. That lets the caller treat them
collectively or individually. They need to be defined at a higher
level than the exceptions being raised inside the implementation. They
have to make sense no matter what the implementation.
Imagine devising a database interface. Your Exceptions would talk
about the database tables and rows, not about file/io screwing up.

Signature
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
Stefan Ram - 22 Sep 2007 21:55 GMT
>If you have a non-trivial interface, you probably should devise
>a set of Exceptions
The exceptions can also be type parameters:
interface Example
< E1 extends java.lang.Throwable, E2 extends java.lang.Throwable >
{ void example() throws E1, E2; }
When an implementation does not need to declare
two exceptions, it can still use this interface
by giving »java.lang.RuntimeException« as type
arguments:
class ExcampleImplementation
implements Example< java.lang.RuntimeException, java.lang.RuntimeException >
{ public void example(){} }
This posting is based on ideas published
in de.comp.lang.java by Ralf Ullrich.