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.

Throwable and Error classes should not be caught

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:

try {
cl = Thread.currentThread().getContextClassLoader();
}catch (Throwable ex) { //Non-compliant code
}

In nutshell, following are some of the reasons:

  • Throwable is the superclass of all errors and exceptions in Java. Error is the superclass of all errors which are not meant to be caught by applications. Thus, catching Throwable would essentially mean that Errors such as system exceptions (e.g., OutOfMemoryError, StackOverFlowError or InternalError) would also get caught. And, the recommended approach is that application should not try and recover from Errors such as these. Thus, Throwable and Error classes should not be caught. Only Exception and its subclasses should be caught.

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.

Throwable.printStackTrace(…) should never be called

Following is an example of code that represents the usage of invocation of printStackTrace on Throwable class.

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:

  • Difficult to Retrieve Logs for Debugging:The logs written using printStackTrace is written to System.err which is hard to route or filter elsewhere. Instead, using Loggers, it is easy to retrieve logs for debugging purpose.
  • Violation of Coding Best Practices:Generally, as per coding guidelines in production-ready applications, developers need to use Logger methods for logging different level of information. However, when it comes to exception handling, the instances of printStackTrace are commonly found in various places. This is, thus, a violation of coding practice and, thus, should be avoided.
  • Following are some good pages explaining the reasons in detail:

Generic exceptions such as Error, RuntimeException, Throwable and Exception should never be thrown

Following are some of the reasons why Generic Exceptions/Throwable should never be thrown:

  • The primary reason why one should avoid throwing Generic Exceptions, Throwable, Error etc is that doing in this way prevents classes from catching the intended exceptions. Thus, a caller cannot examine the exception to determine why it was thrown and consequently cannot attempt recovery.
  • Additionally, catching RuntimeException is considered as a bad practice. And, thus, throwing Generic Exceptions/Throwable would lead the developer to catch the exception at a later stage which would eventually lead to further code smells.

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.

Java – Top 5 Exception Handling Coding Practices to Avoid的更多相关文章

  1. Exception (3) Java exception handling best practices

    List Never swallow the exception in catch block Declare the specific checked exceptions that your me ...

  2. Java – 4 Security Vulnerabilities Related Coding Practices to Avoid---reference

    This article represents top 4 security vulnerabilities related coding practice to avoid while you ar ...

  3. JAVA fundamentals of exception handling mechanism

    Agenda Three Categories Of Exceptions Exceptions Hierarchy try-catch-finally block The try-with-reso ...

  4. Java exception handling best practices--转载

    原文地址:http://howtodoinjava.com/2013/04/04/java-exception-handling-best-practices/ This post is anothe ...

  5. [fw]Best Practices for Exception Handling

    http://www.onjava.com/pub/a/onjava/2003/11/19/exceptions.html http://www.onjava.com/pub/a/onjava/200 ...

  6. Exception (2) Java Exception Handling

    The Java programming language uses exceptions to handle errors and other exceptional events.An excep ...

  7. Exception Handling Considered Harmful

    异常处理被认为存在缺陷 Do, or do not. There is no try. - Yoda, The Empire Strikes Back (George Lucas) by Jason ...

  8. [转]java-Three Rules for Effective Exception Handling

    主要讲java中处理异常的三个原则: 原文链接:https://today.java.net/pub/a/today/2003/12/04/exceptions.html Exceptions in ...

  9. Java Tips and Best practices to avoid NullPointerException

    A NullPointerException in Java application is best way to solve it and that is also key to write rob ...

随机推荐

  1. Tomcat基于MSM+Memcached实现Session共享

    简述 上一篇文章,分别演示了session sticky 和 session cluster来实现会话保持的问题,但是它们缺点都不少,实际中用的很少,所以这篇文章我们还是通过Tomcat来演示一下实际 ...

  2. dubbo-demo的运行

    在学习dubbo时,最主要的是将dubbo运行起来. 现在先搭建起来简单的demo. 一:安装zookeeper(在wondows下安装,且是单机模式) 1.下载zookeeper 2.下载的版本 3 ...

  3. 2017-2018-1 20179202《Linux内核原理与分析》第七周作业

    一 .Linux内核创建一个新进程的过程 1. 知识准备 操作系统内核三大功能是进程管理,内存管理,文件系统,最核心的是进程管理 linux 进程的状态和操作系统原理的描述进程状态有所不同,比如就绪状 ...

  4. 第1天:Django框架简介与工程创建

    Django简介 Django特点 环境搭建 创建工程 启动服务 使用pycharm打开工程 创建子应用 Django简介 Django,是用Python语言写的开源web开发框架,并遵循MVC设计. ...

  5. eclipse使用小技巧

    1.eclipse中SVN无版本信息显示,window-preference-general-appeerance-label decoration-svn勾上,显示有关项目中受 SVN 控制的资源的 ...

  6. 机器学习之路:python k近邻回归 预测波士顿房价

    python3 学习机器学习api 使用两种k近邻回归模型 分别是 平均k近邻回归 和 距离加权k近邻回归 进行预测 git: https://github.com/linyi0604/Machine ...

  7. Redis 服务器命令

    1.BGREWRITEAOF 异步执行一个 AOF(AppendOnly File) 文件重写操作 2.BGSAVE 在后台异步保存当前数据库的数据到磁盘 3.CLIENT KILL [ip:port ...

  8. Ubuntu安装redis和redis-php扩展

    通过apt-get安装的redis使用方法 sudo apt-get install redis-server sudo apt-get install php-redis vim /etc/redi ...

  9. 优客365 v2.9版本 后台存在SQL注入

    安装 打开后台登陆界面 http://localhost:9096/yk365/system/login.php 输入单引号报错 得到表名 经过跟踪后在\module\login.php文件出现错误 ...

  10. Shell 学习笔记之传递参数

    传递参数 设置权限 chmod +x file.sh 传递参数 ./file.sh parameter1 ... 特殊字符 $# 传递到脚本的参数个数 $* 以一个单字符串的形式显示所有向脚本传递的参 ...