This article represents top 5 coding practices related with Java exception handling that you may want to watch out for or better say, avoid, while doing coding for exception handling. Recently, I have been involved with code review of multiple Java projects and found following as most commonly seen coding instances across various Java projects. As a matter of fact, I recently ran sonar code analysis on Spring Core project (Spring Framework) and found the below mentioned instances related with exception handling. Please note that these are suggested to be avoided as a general coding practice and do not mean that they can not be used at all. There are still cases where one may end up using coding practice against following, but that should happen on case-to-case basis and not as a general practice. Please feel free to comment/suggest if I missed to mention one or more important points. Also, sorry for the typos.html
Throwable and Error classes should not be caughtjava
One should try and avoid catching Throwable and Errors in their code. There is a very detailed article written on this topic on this page. Following is an example of non-compliant code taken from Spring-core code:shell
try { cl = Thread.currentThread().getContextClassLoader(); }catch (Throwable ex) { //Non-compliant code
}
In nutshell, following are some of the reasons:app
Above said, there are reasons why people still go for catching Throwable. The data errors such as encoding issues etc which are not known at programming time can be caught using this technique. However, catching Throwable such as InternelError or OutofMemoryError would not be of any help and should therefore be thrown. Thus, one should avoid writing code consisting of catching Throwable as general practice.ide
Throwable.printStackTrace(…) should never be calledui
Following is an example of code that represents the usage of invocation of printStackTrace on Throwable class.this
try { /* ... */ } catch(Throwable e) { e.printStackTrace(); // Non-Compliant
}
Following are some of the reasons why one should avoid invoking printStackTrace method on Throwable/Exception classes and instead use Logger method using one of the frameworks such as LogBack or Log4J:spa
Generic exceptions such as Error, RuntimeException, Throwable and Exception should never be throwndebug
Following are some of the reasons why Generic Exceptions/Throwable should never be thrown:code
Following is the code sample that represents this code smell:
public void foo(String bar) throws Throwable { // Non-compliant
throw new RuntimeException("My Message"); // Non-Compliant
} // One other instance which displays throwing Exception
public void doSomething() throws Exception {...} // Non-compliant code
Instead, one would want to do something like following:
public void foo(String bar) { throw new CustomRuntimeException("My Message"); // Compliant
}
Exception handlers should preserve the original exception
When writing code for doing exception handling, I have often seen code such as following which does some of the following:
In the code sample below, the exception is lost.
try { /* ... */ } catch( Exception e ) { // The exception is lost. Just that exception message is written; Also, context information is not logged.
SomeLogger.info( e.getMessage() ); }
In the code sample below, whole exception object is lost.
try { /* ... */ } catch( Exception e ) { SomeLogger.info( "some context message" ); // The exception is lost
}
In the code sample below, no context message is provided.
try { /* ... */ } catch( Exception e ) { SomeLogger.info( e ); // No context message
}
As a best practice, one would want to do something like following:
try { /* ... */ } catch( Exception e ) { // Context message is there. Also, exception object is present
SomeLogger.info( "some context message", e ); }
In case of throwable exceptions, following should be done:
try { /* ... */ } catch (Exception e) { // Context message is there. Also, exception object is present
throw new CustomRuntimeException("context", e); }
System.out or System.err should not be used to log exceptions
The primary reason why one should avoid using System.out or System.err to log exception is the fact that one might simply loose the important error messages. Instead one should use Logging frameworks such as Log4J or LogBack etc to log the exceptions.