Effective Java Exceptions
A new article by Barry Ruzek on BEA's dev2dev site discusses the use of exceptions in Java and proposes a way of thinking about exceptions to help guide when to use checked versus unchecked exceptions. It separates exceptional conditions into faults and contingencies and describes how to handle each.
Ruzek argues that those who say Java's checked exceptions are a failed experiment are wrong. The Java library designers failed to acknowledge the two basic causes for method failure, resulting in the overuse of checked exeptions. Ruzek posits that the two causes for method failure are:
- Contingency - An expected condition demanding an alternative response from a method that can be expressed in terms of the method's intended purpose. The caller of the method expects these kinds of conditions and has a strategy for coping with them.
- Fault - An unplanned condition that prevents a method from achieving its intended purpose that cannot be described without reference to the method's internal implementation.
In his example of a CheckingAccount class in a banking system, stop payment orders or overdrafts are contingencies, while the database being down or a network cable unplugged are faults. Based on this breakdown, contingencies should be handled with checked exceptions and faults with unchecked exceptions.
When processing faults, unchecked exceptions fits with the design of the JRE (ArithmeticException and ClassCastException are RuntimeException subclasses), and minimizes clutter because methods upstream of the fault do not all need to handle or explicitly pass the exception on. Furthermore, he suggests in most cases you can use RuntimeException itself, rather than a subclass. Most of the time you only need to pass on a message, as the exceptions are chained (from 1.4 on). Ruzek lists four goals for handling faults:
- Minimize code clutter
- Capture and preserve diagnostics
- Alert the right person
- Exit the activity gracefully
To handle faults, he recommends a fault barrier, which he describes here:
The goal here is to free the functional portions of your application from the responsibility of processing faults. Separation of concerns is generally a good thing, and a central facility responsible for dealing with faults will pay benefits down the road. In the fault barrier pattern, any application component can throw a fault exception, but only the component acting as the "fault barrier" catches them. Adopting this pattern eliminates much of the intricate code that developers insert locally to deal with faults. The fault barrier resides logically toward the top of the call stack where it stops the upward propagation of an exception before default action is triggered.
The fault barrier will log the information to the application log file and then close the operation in a controlled manner. For contingencies he recommends extending Exception to add value or information to the message passed back and not to bother with logging. He argues that since they are expected conditions, logging merely informs you that the application is working as designed. If a contingency represents a significant event, that should be logged before the exception is thrown.
Lastly, Ruzek points out that aspect oriented programming provides a excellent way to handle faults and contingencies, as they are cross-cutting concerns.
Un-Effective Java Exceptions
Re: Un-Effective Java Exceptions
Because of this glaring problem it is completely clear that (a) no classification based checking system (Java) will EVER be workable (as you're pointing out) nor will (b) the LACK of a checking system (.NET CLR).
The only sane way to deal with this whole mess is to do exception checking based on scope based usage contracts. Special declarations may be necessary to deal with dynamic code such as in interface boundaries (where it cannot be determined apriori what exceptions might be thrown), but the basic idea is pretty straightforward. You declare how different USAGE scopes either check or don't check different classes of exceptions. The compiler can then warn you about the branchable exceptional conditions you WANT to be warned about without telling you about terminal exceptional conditions you DON'T WANT to be told about.
Updated link to the actual article
Re: Updated link to the actual article