Thursday, June 28, 2007

Checked or unchecked exceptions

Every Java developer at one point in her career needs to decide how to convey an exception/error to other layers of application.

Hopefully someone in her organization clearly communicated how exceptions should be handled to her. This is one of the important duties of enterprise architects, mentors, senior developers.

Some would argue that checked exceptions have no place in code, while others argue that there is a place for them.

I find the following piece very informative and balanced.

Here are some key things i hold dear:

1- Differentiate between fault and contingencies. Represent faults with unchecked exceptions.
"Can not connect to server" type errors fall in the category of faults.

2- Try to minimize the use of checked exceptions especially if you are developing an API that will be used by lots of modules/components. Checked exceptions are viral and tend to pollute codebase with unnecessary trycatchfinally blocks.
Remember that you can use try finally block without catching anything in between...
Often times there are other ways of doing it too.

For example following fictitious method throws InSufficientBalanceException if payment amount is larger than account balance.
doPay(Payment p) throws InSufficientBalanceException()

Clients of this method will catch the exception and try to recover from it later.


A much more clean design would be like this.
------
boolean isBalanceEnough(Payment p)
doPay(Payment p) // throws unchecked exception
------

Above API needs to be used in a disciplined strict way. (API is based on a contract.)
------
if(! isBalanceEnough(p)){
// transfer some money from other account
}
doPay(p)
------
Unit tests, code inspections/reviews are expected to spot any misuse of API. Better yet "design by contract" is emerging in Java realm with the advent of annotations.
Then the method signature will look like this.

@pre("
isBalanceEnough(p)")
public void doPay(Payment p)


3- Dont try to shape program flow with exceptions. Exceptions should be exceptional.
Especially input validation shall not be done with exceptions. Because users are expected to put bad input almost regularly and throwing exception on first invalid input is bad practice. Instead collect all validation results and display them at once.


4- Dont ever swallow exceptions without doiny anything.

try{
// do something
}catch(Throwable t){}


Above code will swallow unchecked exceptions too! Welcome to the endless sessions of debugging!!

What are your guidelines for dealing with exceptions and errors in your programs?

No comments: