Re: Handling exceptions
ahjiang@gmail.com wrote:
int foo() {
try {
do something;
return SUCCESS;
}catch(Exception e){
print e;
}finally{
return FAILURE;
}
}
I understand that failure will always be returned because of the
finally clause.
What is the best practice to return a value if success or failure.
Or should the exception be propagated to the calling method?
Use exceptions for fault reporting. Return values are often difficult
for client code and have a long history of being ignored (for instance
in a live system the cd command failed one day in `cd xyz ; rm -rf *`).
Also you wont be able to use a return value (sensibly) if it is already
used to signal faults.
If you must return an error status, write it something like:
BarErrorStatus foo() {
try {
do something;
return BarErrorStatus.SUCCESS;
} catch (SomeException exc) {
// [ Or something at least a little descriptve. ]
return BarErrorStatus.FAILURE;
}
}
If you use a variable for status for some reason (for instance for use
in code following the try/catch/finally), if you leave it unassigned
until as late as possible, you can use the definite
assignment/unassignment rules to catch errors:
void foo() {
BarErrorStatus errorStatus;
try {
do something;
errorStatus = BarErrorStatus.SUCCESS;
} catch (SomeOtherException exc) {
exc.printStackTrace(); <-- Compiler error.
} catch (SomeException exc) {
// [ Or something at least a little descriptve. ]
errorStatus = BarErrorStatus.FAILURE;
}
if (errorStatus == BarErrorStatus.SUCCESS) {
blah;
}
}
It is (or should be) rare to catch
Exception/Throwable/Error/RuntimeException.
Sometimes, you do need a status flag:
Connection openConnection() throws ConnectionException {
boolean succeeded = false;
Connection raw = new RawConnection(someField);
try {
Connection buffered = new BufferedConnection(raw);
succeeded = true;
return buffered;
} finally {
if (!succeeded) {
raw.close();
}
}
}
(Although most people seem to like to leak resources instead...)
Tom Hawtin