Chris Smith said:
I'm not sure I agree. Exceptions should, of course, be caught in the
"right" place, by which I mean the place that best balances various
development concerns. Sometimes that place is closer to the middle (for
example, five methods up, but not the seventeen methods all the way to
the root of the call tree.)
If "five methods up" is still within the same logical layer of your
application, the same layer of abstraction, then letting the exception
live until can make perfect sense. That is still near enough for me to
call it near

It's when exceptions survive to a different level of
abstraction, where there is no chance that the receiver even understands
it, that something should be done.
In that case, you catch the exception, wrap it, and rethrow. That
doesn't really count as catching for the purposes of this conversation.
Indeed, it doesn't seem like it matches any of the cases below
.... except that it is exactly how I would implement number one (which
is therefore also the one that I would pick).
So, back in context again, the question is what to do with an exception
that is thrown during an OutputStream.close() operation.
Nasty place, indeed. And
The options were:
1. Don't catch it, and let it be handled elsewhere, realizing that this
could mask another I/O exception that was thrown earlier.
Since the exception thrown by OutputStream.close() is probably an
IOException, a checked exception, simply passing it outwards will
leave "throws IOException" all over the code upwards from there.
Catching the IOException and throwing a more meaningfull exception,
one that can be understood by the code receiving it, is not only
prettier, it also avoids exposing an implementation detail in the
signature of your method.
If there is no reasonable way for the calling code to handle an
exception at this point, it should perhaps be a runtime exception.
Runtime exceptions should generally not be caught (if they are thrown
appropriatly

so that would mean the death of the program if not
caught by a very high level handler ... if such one makes sense.
2. Catch it and continue without reacting (perhaps some logging or other
reporting could be done, but it would have to be done from a catch
clause inside a finally block at the leaves of the call tree).
Proceeding should only be an option if the program knows it to be
safe, and that it is indeed the best cause of action. For this exact
exception, that is unlikely, but I bet there is at least one example
where it is.
3. Set a boolean flag of some sort, and write your own logic to replace
the normal throw/catch exception control flow.
Reinventing the wheel ... only square

That would almost be back to
the C way of handling exceptional conditions: returning -1
I'm voting for #1. It leads to simpler code, less likelihood of missing
an important exception, and no substantial decrease in the likelihood of
having enough information to troubleshoot the original problem.
I agree, provided that it includes wrapping the exception when it
passes abstraction layers.
It doesn't really help for you to say that this should be done in a
"top-level handler", since the question is how to deal with issues
in a try/finally block, and we're not even dealing with how the
exception is handled from elsewhere in the call tree.
Whenever you throw an exception, you should be aware who, if any, will
catch it. Not the exact code, obviously, but what their role is in
calling you and what exceptions would make sense to them.
A top-level handler in an application is really a nobody. It has no
role related to you, so it's not really any better than having the
exception terminate the program. It's just the only case I can find
for not catching an exception close to where it is thrown (which
might include wrapping it and rethrowing).
/L