Checked Exceptions!

  • Thread starter Thread starter OvErboRed
  • Start date Start date
ncaHammer said:
I find checked exceptions awful in theory too !
Checked exceptions abuse the exception mechanism by using it (basically)
instead of return values

They tie the *caller* to a contract, destroying the basic purpose of why we
have structured exceptions in the first place.

While exceptions can trace the stack for a handler without limitations (many
levels), checked exceptions enforce a first level resolution always.

Only if you think you always have to actually catch them, or if you
deem letting them automatically propagate up the stack to be "first
level resolution".
 
Jon Skeet said:
Only if you think you always have to actually catch them, or if you
deem letting them automatically propagate up the stack to be "first
level resolution".

altering method signature so the exception can propagate *is*
"first level resolution" too
 
ncaHammer said:
altering method signature so the exception can propagate *is*
"first level resolution" too

I don't think that deciding not to deal with it counts as resolution,
myself.

I don't think we're going to agree on this issue either though...
 
So are the pro-checked exception reasons!
If documentation about which exceptions a method can throw is not
enough, what is?
different implementations which can throw different exceptions,
however when you define them as checked in the interface, you are not
able to do that.

Far from being an issue of sloppiness, the absence of checked exceptions
presents a very real limitation to the design of well-encapsulated
components. Documentation is important, of course; nobody's questioning
that. However, if documentation were enough, then return- and parameter-
checking would be extraneous as well. You will probably argue that
exceptions are different because they are more closely related to the
implementation. However, that's the crux of the problem: interfaces are
supposed to prevent implementation details from being exposed.

But just as you're not limited to returning the exact type specified in
a method signature, you aren't being crippled by checked exceptions.
Make no mistake about it. As long as any inner exception is a subclass
of or wrapped in an instance of the throwable types that are permitted
by the interface, nothing prevents you from passing back any extended
data specific to the implementation at hand.

In fact, checked exceptions offer a safer way to throw your own
exceptions, because you'll know that doing so won't break the calling
code if it's not expecting your particular exception's runtime type.
That's what it all boils down to: by replacing the underlying
implementation without making any guarantees on the type of data to
expect, you aren't running the risk of an unexpected exception bubbling
up clear off the stack or of needing to rewrite code everywhere, as is
currently the case with .NET.



Finally, if you're still not convinced, remember that you'd be free to
automagically add "throws Exception" to all your methods and resume your
work hassle-free. =)
 
Far from being an issue of sloppiness, the absence of checked exceptions
presents a very real limitation to the design of well-encapsulated
components. Documentation is important, of course; nobody's questioning
that. However, if documentation were enough, then return- and parameter-
checking would be extraneous as well. You will probably argue that
exceptions are different because they are more closely related to the
implementation. However, that's the crux of the problem: interfaces are
supposed to prevent implementation details from being exposed.

exactly, so interfaces should not have any information about the
implementation details. No offence, but if an interface defines 'Throws
FileIOException' it clearly defines that the implementation can/should
access files, however that's probably not the case. So it tells the caller
FALSE information. This is something different than an implementation of
the interface defines that it throws FileIOException, since it then is
legitimate to say 'I throw exception xyz', because we're talking about a
given implementation then.
But just as you're not limited to returning the exact type specified in
a method signature, you aren't being crippled by checked exceptions.
Make no mistake about it. As long as any inner exception is a subclass
of or wrapped in an instance of the throwable types that are permitted
by the interface, nothing prevents you from passing back any extended
data specific to the implementation at hand.

True, but for exceptions I'd like to make an erm.. exception :) If
the returntype is a given baseclass, code calling the method can work with
the base class, otherwise they wouldn't have called the method. However,
an exception thrown should TELL what is wrong, not being a flag that says
'Hi, something was wrong, look inside my tree of inner exceptions to see
what's wrong', because you can't catch inner exceptions. Exceptions thrown
therefore have to match exactly what went wrong. Encapsulation of
exceptions in higher order exception classes is therefore making
exceptions a moot technology.
In fact, checked exceptions offer a safer way to throw your own
exceptions, because you'll know that doing so won't break the calling
code if it's not expecting your particular exception's runtime type.
That's what it all boils down to: by replacing the underlying
implementation without making any guarantees on the type of data to
expect, you aren't running the risk of an unexpected exception bubbling
up clear off the stack or of needing to rewrite code everywhere, as is
currently the case with .NET.

Of course you do run the risk! If a new implementation implements
the interface differently and has to encapsulate a new exception into a
higher order exception to avoid breakage of the exception definition in
the interface, you're creating poopcode.

I see exceptions as: if the DIRECT caller can recover from a given
set of exceptions, catch these and recover there, and bubble up the rest,
because these are fatal for that position in the call stack and perhaps a
higher level in the callstack can recover from these. New exceptions in a
new implementation of an interface can be handled then as such, they end
up as being 'fatal' and will report an error message or abort a
transaction or whatever. Eric Gunnerson has enlisted these situations
before, in the mile long thread about the same topic :)
Finally, if you're still not convinced, remember that you'd be free to
automagically add "throws Exception" to all your methods and resume your
work hassle-free. =)

Yeah right. If that is necessary 'checked exceptions' is useless.
If a given rule enforces you to do something but can be overcome by
cheating (like throws Exception) the 'enforcement' is not mandatory
anymore so callers of code defining exceptions can't rely on the list they
see and therefore you can also just say 'no' to checked exceptions and
save you all the trouble.

FB
 
Jon Skeet said:
Most of the time, it works very well, in my experience. The interface
designer needs to be careful, of course, but they should include
exceptions which match what was meant to happen, and allow exception
chaining to give specific exceptions. For instance, when performing
some database operation, it makes sense for a SqlException to be thrown
even if underlying that there was an IOException (which is then chained
onto the SqlException).

I disagree. Knowing that the ultimate case was, e.g. FileIOException tells
the user that the corrective action to take involves the file system rather
then something else. Mapping this to a SQLException is misleading.
Where it becomes a little messier is where there will *always* be a
chained exception, and the original exception is virtually never
meaningful in itself - for instance, if an iterator had an
IterationException, it would usually be because something underneath
had caused a problem.

If calling code has to examine the inner exception in order to determine
what happened and how to take corrective action then much of the benefit of
checked exceptions is lost. Hiding details of the cause of an error is, in
many cases, the wrong approach to take.

My current position on exceptions is to use exception chaining extensively.
At each major logical transition I add another try-catch layer; if an
exception is caught it adds some context information and rethrows the
exception. At some higher layer (e.g. the UI) it unrolls all the exceptions
and presents them to the user. Corrective action is taken at the lowest
level possible, which varies based on the operation being performed.
Having used both Java and C# fairly extensively now, I can see how not
having checked exceptions makes the C# coding quicker - particularly
when you're writing quick test code rather than production code - but I
still think the Java approach prods the developer to consider possibly
error routes more.

--
I am in favor of there being more discipline in error/exception handling;
this is an area that needs a lot more work, both conceptually and in how
people use it.

In this discussion there are a lot of unexamined assumptions. Many of the
arguments make sense when applied to the small case but tend to make less
sense when applied to the situations most developers run into and in large
systems.

For example, should a web service throw exceptions across a web method
boundary (I know it can, but should it)? Should the web method define what
exceptions it throws (if the answer is yes then a lot of work needs to be
done to tools such as wsdl).

It seems to me that checked exception definitions are one of those ideas
that sounds great on paper but in practice either create new problems or
don't fully solve the current problem. I'd like to see more theoretical work
done in this area. I also believe that treating exceptions thrown as part of
the type definition and including it in the metadata would make it more
practical to implement an exception management strategy.
 
Dave said:
I disagree. Knowing that the ultimate case was, e.g. FileIOException tells
the user that the corrective action to take involves the file system rather
then something else. Mapping this to a SQLException is misleading.

I guess we disagree then. In my view, the exception thrown should
always have something to do with the activity the caller is dealing
with.
If calling code has to examine the inner exception in order to determine
what happened and how to take corrective action then much of the benefit of
checked exceptions is lost. Hiding details of the cause of an error is, in
many cases, the wrong approach to take.

It's not hiding them - it's storing them but giving a more general view
at the top level.

In my experience, "corrective action" is rarely taken due to
exceptions. I rarely try to fix something and then try again - I
usually log/report the error, and deal with the fact that I couldn't do
what I wanted to (whatever that entails). There are occasions where
it's possible to try again with something different, but they're not
common IME.
My current position on exceptions is to use exception chaining extensively.
At each major logical transition I add another try-catch layer; if an
exception is caught it adds some context information and rethrows the
exception. At some higher layer (e.g. the UI) it unrolls all the exceptions
and presents them to the user. Corrective action is taken at the lowest
level possible, which varies based on the operation being performed.

That sounds similar to what I was proposing though...
I am in favor of there being more discipline in error/exception handling;
this is an area that needs a lot more work, both conceptually and in how
people use it.

Agreed. I'm not saying I've got all the answers or that I do things
particularly well, either :(
In this discussion there are a lot of unexamined assumptions. Many of the
arguments make sense when applied to the small case but tend to make less
sense when applied to the situations most developers run into and in large
systems.

For example, should a web service throw exceptions across a web method
boundary (I know it can, but should it)? Should the web method define what
exceptions it throws (if the answer is yes then a lot of work needs to be
done to tools such as wsdl).

I'd say yes to both, offhand - but I haven't used web services much, to
be honest.
It seems to me that checked exception definitions are one of those ideas
that sounds great on paper but in practice either create new problems or
don't fully solve the current problem. I'd like to see more theoretical work
done in this area. I also believe that treating exceptions thrown as part of
the type definition and including it in the metadata would make it more
practical to implement an exception management strategy.

I certainly don't think they fully solve the current problem - but in
many cases I believe they solve the current problem better than not
having anything but documentation.
 
Back
Top