1. Overview

In this article, we’ll have a very brief look at what Exception is and go in depth about discussing the chained exceptions in Java.

Simply put, an exception is an event that disturbs the normal flow of the program’s execution. Let’s now see exactly how we can chain exceptions to get better semantics out of them.

2. Chained Exceptions

Chained Exception helps to identify a situation in which one exception causes another Exception in an application.

For instance, consider a method which throws an ArithmeticException because of an attempt to divide by zero but the actual cause of exception was an I/O error which caused the divisor to be zero.The method will throw the ArithmeticException to the caller. The caller would not know about the actual cause of an Exception. Chained Exception is used in such situations.

This concept was introduced in JDK 1.4.

Let’s see how chained exceptions are supported in Java.

3. Throwable Class

Throwable class has some constructors and methods to support chained exceptions. Firstly, let’s look at the constructors.

  • Throwable(Throwable cause) – Throwable has a single parameter, which specifies the actual cause of an Exception.
  • Throwable(String desc, Throwable cause) – this constructor accepts an Exception description with the actual cause of an Exception as well.

Next, let’s have a look at the methods this class provides:

  • getCause() method – This method returns the actual cause associated with current Exception.
  • initCause() method – It sets an underlying cause with invoking Exception.

4. Example

Now, let’s look at the example where we will set our own Exception description and throw a chained Exception:

1
2
3
4
5
6
7
8
9
10
11
12
public class MyChainedException {
 
    public void main(String[] args) {
        try {
            throw new ArithmeticException("Top Level Exception.")
              .initCause(new IOException("IO cause."));
        } catch(ArithmeticException ae) {
            System.out.println("Caught : " + ae);
            System.out.println("Actual cause: "+ ae.getCause());
        }
    }   
}

As guessed, this will lead to:

1
2
Caught: java.lang.ArithmeticException: Top Level Exception.
Actual cause: java.io.IOException: IO cause.

5. Why Chained Exceptions?

We need to chain the exceptions to make logs readable. Let’s write two examples. First without chaining the exceptions and second, with chained exceptions. Later, we will compare how logs behave in both of the cases.

To start, we will create a series of Exceptions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class NoLeaveGrantedException extends Exception {
 
    public NoLeaveGrantedException(String message, Throwable cause) {
        super(message, cause);
    }
 
    public NoLeaveGrantedException(String message) {
        super(message);
    }
}
 
class TeamLeadUpsetException extends Exception {
    // Both Constructors
}

Now, let’s start using the above exceptions in code examples.

5.1. Without Chaining

Let’s write an example program without chaining our custom exceptions.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class MainClass {
 
    public void main(String[] args) throws Exception {
        getLeave();
    }
 
    void getLeave() throws NoLeaveGrantedException {
        try {
            howIsTeamLead();
        } catch (TeamLeadUpsetException e) {
            e.printStackTrace();
            throw new NoLeaveGrantedException("Leave not sanctioned.");
        }
    }
 
    void howIsTeamLead() throws TeamLeadUpsetException {
        throw new TeamLeadUpsetException("Team Lead Upset");
    }
}

In the example above, logs will look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
com.baeldung.chainedexception.exceptions.TeamLeadUpsetException:
  Team lead Upset
    at com.baeldung.chainedexception.exceptions.MainClass
      .howIsTeamLead(MainClass.java:46)
    at com.baeldung.chainedexception.exceptions.MainClass
      .getLeave(MainClass.java:34)
    at com.baeldung.chainedexception.exceptions.MainClass
      .main(MainClass.java:29)
Exception in thread "main" com.baeldung.chainedexception.exceptions.
  NoLeaveGrantedException: Leave not sanctioned.
    at com.baeldung.chainedexception.exceptions.MainClass
      .getLeave(MainClass.java:37)
    at com.baeldung.chainedexception.exceptions.MainClass
      .main(MainClass.java:29)

5.2. With Chaining

Next, let’s write an example with chaining our custom exceptions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class MainClass {
    public void main(String[] args) throws Exception {
        getLeave();
    }
 
    public getLeave() throws NoLeaveGrantedException {
        try {
            howIsTeamLead();
        } catch (TeamLeadUpsetException e) {
             throw new NoLeaveGrantedException("Leave not sanctioned.", e);
        }
    }
 
    public void howIsTeamLead() throws TeamLeadUpsetException {
        throw new TeamLeadUpsetException("Team lead Upset.");
    }
}

Finally, let’s look at the logs obtained with chained exceptions:

1
2
3
4
5
6
7
8
9
10
11
12
13
Exception in thread "main" com.baeldung.chainedexception.exceptions
  .NoLeaveGrantedException: Leave not sanctioned.
    at com.baeldung.chainedexception.exceptions.MainClass
      .getLeave(MainClass.java:36)
    at com.baeldung.chainedexception.exceptions.MainClass
      .main(MainClass.java:29)
Caused by: com.baeldung.chainedexception.exceptions
  .TeamLeadUpsetException: Team lead Upset.
    at com.baeldung.chainedexception.exceptions.MainClass
  .howIsTeamLead(MainClass.java:44)
    at com.baeldung.chainedexception.exceptions.MainClass
  .getLeave(MainClass.java:34)
    ... 1 more

We can easily compare shown logs and conclude that the chained exceptions lead to cleaner logs.

6. Conclusion

In this article, we had a look at chained exceptions concept.

The implementation of all examples can be found in the Github project – this is a Maven-based project, so it should be easy to import and run as it is.

Chained Exceptions in Java的更多相关文章

  1. redis报错:java.net.SocketException: Broken pipe (Write failed); nested exception is redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Broken pipe (Write failed)

    最近写了一个服务通过springboot构建,里面使用了redis作为缓存,发布到服务器运行成功,但是有时候会报redis的错误:org.springframework.data.redis.Redi ...

  2. redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: 断开的管道 (Write failed)

    昨晚,包发到测试环境中,出现redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: 断开的 ...

  3. Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: connect timed out

    问题: java连接不上redis. 异常信息: Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.ne ...

  4. Exception in thread "main" redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused (Connection refused)

    一.linux中配置redis,使用java连接测试时报错: Exception in thread "main" redis.clients.jedis.exceptions.J ...

  5. redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: connect time out

    redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: connect ti ...

  6. Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十二)之Error Handling with Exceptions

    The ideal time to catch an error is at compile time, before you even try to run the program. However ...

  7. Checked exceptions: Java’s biggest mistake-检查型异常:Java最大的错误(翻译)

    原文地址:http://literatejava.com/exceptions/checked-exceptions-javas-biggest-mistake/ 仅供参考,毕竟我四级都没过 Chec ...

  8. Java编程思想 (1~10)

    [注:此博客旨在从<Java编程思想>这本书的目录结构上来检验自己的Java基础知识,只为笔记之用] 第一章 对象导论 1.万物皆对象2.程序就是对象的集合3.每个对象都是由其它对象所构成 ...

  9. java异常拾遗

    概述 当方法内部发生一项错误时,该方法会创建一个对象传递给运行时系统(runtime system),这个对象被称为异常对象,包含错误的类型.发生位置,程序状态等一系列信息. 当一个方法抛出异常时,运 ...

随机推荐

  1. ORA-01555错误

    有这样一种情况 0:00 我们开始查询,查询的数据是100万条 0:01 一个session update了第100万条数据 0:01 update提交了,完成 1:00 我们的查询还在继续,只读到了 ...

  2. [js]es6语法: 字符串和数组的方法

    s的方法 根据index取value: 取首尾项,arr[0], arr[arr.length-1] 根据value取index(判断是否包含子字符串): s.indexOf 栗子: 'maotai' ...

  3. 3.1.2 Spring之IoC

    二.Spring之IoC 1. IoC与DI (1) IoC 控制反转( IoC, Inversion of Control) , 是一个概念, 是一种思想. 控制反转就是对对象控制权的转移, 从程序 ...

  4. linux affinity

    现在的CPU几乎都是多核,所以,分配给予进程相同数量的线程是合理的需求 但是,这些线程不一定就均匀跑在这些内核上 所以,我们要指派,“一个线程就运行在一个固定的CPU内核上” //test.c #de ...

  5. VC++运行库 集32位/64位整合版

    运行程序时,win7/win10(x86和x64)常会遇到缺少什么缺少msvc***.dll问题 安装下面链接提供的程序,安装后,便可解决. [2016-10-10]Microsoft Visual ...

  6. 实现Runnable接口创建多线程及其优势

    实现Runnable接口创建多线程: 创建一个Runnable接口的实现类RunnableImpl: 主线程中: 其中,链式编程的Thread类的静态方法currentThread方法点getName ...

  7. 在Qt Quick中一个简单Hello World加载过程

    Qt5基本类图: QQmlEngine    QQmlEngine类提供了一个QML引擎,用于管理由QML文档定义的对象层次架构,QML提供了一个默认的QML上下文(根上下文,获取函数QQmlEngi ...

  8. 裸奔的bootloader单步调试

    2011-03-01 23:25:22 目地:更清晰的了解bootloader的结构及功能.为移植U-boot打基础. 以前只知道大概,今天利用IAR调试工具,看着汇编代码,看着寄存器,看着内存.来单 ...

  9. Html select、option、optgroup 标签

    Html select 标签 </body> </html> <!-- select外部下拉选择框.name="xxx"标识后端获取名称 --> ...

  10. Docker Swarm 服务版本更新与回滚

    Docker Swarm 服务版本更新 环境: 系统:Centos 7.4 x64 应用版本:Docker 18.09.0 管理节点:192.168.1.79 工作节点:192.168.1.78 工作 ...