This is intended as a dumping ground for all the tips on using exceptions that I accumulate over the years.
Don't swallow exceptions
Never, ever do this:
try {
...
} catch (IOException ioe) {
// do nothing here
}
Always log a message, or print a stacktrace, or re-throw the exception, or throw a new exception (and wrap the caught exception).
Allow your checked exceptions to wrap other exceptions
class MyException extends Exception {
public MyException(String message, Throwable cause) {
super(message, cause);
}
}
This is almost always useful. You will often find yourself catching an IOException and re-throwing it as your own exception. The main point is DON'T DISCARD THE ORIGINAL EXCEPTION. If you do, you won't see it any stack traces as the "caused by:" exception.
Don't log an exception that you are re-throwing or wrapping
This is a minor detail but it makes for much cleaner logs.
try {
...
} catch (IOException ioe) {
log.error("Got an IOException", ioe); // not necessary
throw new MyException("Had a problem contacting the server on port " + port, ioe);
}
In the above, assuming the logger is log4j or something similar, it is going to print the stacktrace for the IOException exception. Then whatever catches MyException up the stack will also log the IOException. This makes for message logging. Either log the IOException and do not wrap the IOException, or don't log it and just wrap it.
Create your own top-level exception classes
I've often found it useful to create two top-level exception classes, one that extends Exception and one that extends RuntimeException. For example, ABCCompanyException and ABCCompanyRuntimeException. Sometimes at the top-level of your application (in the main() method or the HTTP request handler, for example) you want to catch everything that hasn't been dealt with yet. It can be useful to handle "ABCCompanyException" and it's sub-classes separately from Java's "Exception" or "ABCCompanyRuntimeException" separately from Java's RuntimeException.
Don't forget to catch run-time exceptions in callback methods
Let's say you're implementing an event handler to be used in a third-party event bus framework, or implementing an "onOpen/onClose/onMessage" type interface for a web socket client. You should wrap the entire body of the method in a try...catch (Throwable t)
otherwise a run-time message might be thrown somewhere, bubble up into the third-party library, and be swallowed there. Do this any time you are implementing a method that you don't actually call yourself. The same thing goes for the run() method in the Runnable class.
Recent comments