zoukankan      html  css  js  c++  java
  • Chained Exceptions in Java

    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.

  • 相关阅读:
    Django REST framework解析器、渲染器、分页
    微前端qiankun从搭建到部署的实践
    前端开发常用免费资源,显著提升工作效率
    Vue切换页面时碰见过中断axios请求的场景吗?如何中断?
    JavaScript与ES的25个重要知识点!
    电脑端支付宝支付 -前端获取支付宝返回的form 以及submit 调用支付扫码页面
    element ui 分页记忆checked
    通过css改变svg img的颜色
    Howler.js Web音频播放终极解决方案
    5、Redis中对Set类型的操作命令
  • 原文地址:https://www.cnblogs.com/sidesky/p/10621600.html
Copyright © 2011-2022 走看看