views:

85

answers:

5

Hello, all.

Seeing a checked expection in API is not rare, one of the most well known examples is IOException in Closeable.close(). And often dealing with this exception really annoys me. Even more annoying example was in one of our projects. It consists from several components and each component declares specific checked exception. The problem (in my opinion) is that at design time it was not exactly known what certain exceptions would be. Thus, for instance, component Configurator declared ConfiguratorExeption. When I asked why not just use unchecked exceptions, I was told that we want our app to be robust and not to blow in runtime. But it seams to be a weak argument because:

  1. Most of those exceptions effectively make app unusable. Yes, it doesn't blow up, but it cannot make anything exepting flooding log with messages.
  2. Those exceptions are not specific and virtually mean that 'something bad happened'. How client is supposed to recover?
  3. In fact all recovering consists from logging exception and then swallowing it. This is performed in large try-catch statement.

I think, that this is a recurring pattern. But still checked exceptions are widely used in APIs. What is the reason for this? Are there certain types of APIs that are more appropriate for checked exceptions?

+2  A: 

Checked Exceptions should only be thrown for things that are 1) Exceptional they are an exception to the rule of success, most poor exception throwing is the terrible habit of defensive coding and 2) Actionable by the client. If something happens that the client of the API can't possibly affect in any way make it a RuntimeException.

fuzzy lollipop
But, for instance, I doubt that `IOException` on `close()` is _always_ actionable by the client. In my experience it is more oftenly not actionable.
Rorick
You make my point for me, that is a problem with the Sun API, not my advice :-)
fuzzy lollipop
+2  A: 

There have been a lot of controversy around this issue.

Take a look at this classic article about that subject http://www.mindview.net/Etc/Discussions/CheckedExceptions

I personally tend to favor the use of Runtime exceptions myself and have started to consider the use of checked exceptions a bad idea in your API.

In fact some very popular Java API's have started to do the same, for instance, Hibernate dropped its use of checked exceptions for Runtime from version 3, the Spring Framework also favor the use of Runtime over checked exceptions.

StudiousJoseph
+2  A: 

One of the problems with large libraries is that they do not document all the exceptions that may be thrown, so your code may bomb at any time if an undocumented RuntimeException just happens to be thrown from deep down code you do not "own".

By explicitly declaring all those, at least the developer using said library have the compiler help dealing with them correctly.

There is nothing like doing forensic analysis at 3 in the morning to discover that some situation triggered such an undeclared exception.

Thorbjørn Ravn Andersen
This is the problem with runtime exceptions, you are completely relying all exception being documented. And yes, it's a pain when some undocumented runtime exception is thrown deep within the code. These types of exceptions can be difficult to test for. The worse case it that it pops up unexpectedly after being deployed.
Steve Kuo
that is what Unit tests are for, not just success scenarios but for failure ones as well
fuzzy lollipop
@fuzzy, you have never, ever encountered a situation in production that didn't happen during development?
Thorbjørn Ravn Andersen
in 20 years on projects with good coverage of unit and integration tests during QA, no, I don't base PROD vs DEV I base issues on PROD vs QA with a competent QA staff. I have designed and implemented systems that serviced millions of users a day that had 100% for years. That means no required updates or patches or anything. Defect free software is possible with the right attention to detail and quality. It is a sad commentary on our field that people "expect" software to be buggy and fail as the norm.
fuzzy lollipop
@fuzzy, was that a no?
Thorbjørn Ravn Andersen
A: 

There's different views on the matter, but I tend to view things as follows:

  • a checked exception represents an event which one could reasonably expect to occur under some predictable, exceptional circumstances that are still "within the normal operating conditions of a program/typical caller", and which can typically be dealt with not too far up the call stack;
  • an unchecked exception represents a condition that we "wouldn't really expect to occur" within the normal running environment of a program, and which can be dealt with fairly high up the call stack (or indeed possibly cause us to shut down the application in the case of a simpler app);
  • en error represents a condition which, if it occurs, we would generally expect to result in us shutting down the application.

For example, it's quite within the realms of a typical environment that under some exceptional-- but fairly predictable-- conditions, closing a file could cause an I/O error (flushing a buffer to a file on closing when the disk is full). So the decision to let Closable throw a checked IOException is probably reasonable.

On the other hand, there are some examples within the standard Java APIs where the decision is less defensible. I would say that the XML APIs are typically overfussy when it comes to checked exceptions (why is not finding an XML parser something you really expect to happen and deal with in a typical application...?), as is the reflection API (you generally really expect class definitions to be found and not to be able to plough on regardless if they're not...). But many decisions are arguable.

In general, I would agree that exceptions of the "configuration exception" type should probably be unchecked.

Remember if you are calling a method which declares a checked exception but you "really really don't expect it to be thrown and really wouldn't know what to do if it were thrown", then you can programmatically "shrug your shoulders" and re-cast it to a RuntimeException or Error...

Neil Coffey
A: 

You can, in fact, use Exception tunneling so that a generic exception (such as your ConfiguratorException) can give more detail about what went wrong (such as a FileNotFound).

In general I would caution against this however, as this is likely to be a leaky abstraction (no one should care whether your configurator is trying to pull its data from the filesystem, database, across a network or whatever)

If you are using checked exceptions then at least you'll know where and why your abstractions are leaky. IMHO, this is a good thing.

CurtainDog