• 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.

  • 相关阅读:
    (七)mysql 记录长度
    (六)列类型
    (五)校对集
    (四)中文数据问题
    Spring Boot Jpa 的使用
    Spring Boot:如何优雅的使用 Mybatis
    Spring Boot:定时任务
    Spring Boot 小技巧
    【重磅】Spring Boot 2.0权威发布
    Spring Boot + Jpa + Thymeleaf 增删改查示例
  • 原文地址:https://www.cnblogs.com/sidesky/p/10621600.html
Copyright © 2020-2023  润新知