Exceptions chaînées en Java

Exceptions chaînées en Java

 

1. Vue d'ensemble

Dans cet article, nous allons examiner très brièvement ce qu'estException et approfondir la discussion sur les exceptions chaînées en Java.

En termes simples, unexception est un événement qui perturbe le déroulement normal de l’exécution du programme. Voyons maintenant comment nous pouvons enchaîner les exceptions pour en tirer une meilleure sémantique.

2. Exceptions enchaînées

LesException chaînés aident à identifier une situation dans laquelle une exception provoque un autreException dans une application.

For instance, consider a method which throws an ArithmeticException en raison d'une tentative de division par zéro mais la cause réelle de l'exception était une erreur d'E / S qui a provoqué la mise à zéro du diviseur. La méthode lèvera lesArithmeticException à l'appelant. L'appelant ne saurait pas la cause réelle d'unException. LeException chaîné est utilisé dans de telles situations.

Ce concept a été introduit dans JDK 1.4.

Voyons comment les exceptions chaînées sont prises en charge en Java.

3. ClasseThrowable

La classeThrowable a quelques constructeurs et méthodes pour prendre en charge les exceptions chaînées. Tout d’abord, regardons les constructeurs.

  • Throwable(Throwable cause)Throwable a un seul paramètre, qui spécifie la cause réelle d'unException.

  • Throwable(String desc, Throwable cause) ce constructeur accepte une description deException avec la cause réelle d'unException également.

Voyons ensuite les méthodes fournies par cette classe:

  • getCause() method - Cette méthode renvoie la cause réelle associée auxException actuels.

  • initCause() method - Il définit une cause sous-jacente en invoquantException.

4. Exemple

Maintenant, regardons l'exemple où nous allons définir notre propre description deException et lancer unException chaîné:

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());
        }
    }
}

Comme on peut le deviner, cela conduira à:

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

5. Pourquoi des exceptions enchaînées?

Nous devons chaîner les exceptions pour rendre les journaux lisibles. Écrivons deux exemples. Premièrement, sans enchaîner les exceptions et deuxièmement, avec des exceptions chaînées. Plus tard, nous comparerons le comportement des journaux dans les deux cas.

Pour commencer, nous allons créer une série d'exceptions:

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
}

Maintenant, commençons à utiliser les exceptions ci-dessus dans les exemples de code.

5.1. Sans chaînage

Écrivons un exemple de programme sans enchaîner nos exceptions personnalisées.

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");
    }
}

Dans l'exemple ci-dessus, les journaux ressembleront à ceci:

com.example.chainedexception.exceptions.TeamLeadUpsetException:
  Team lead Upset
    at com.example.chainedexception.exceptions.MainClass
      .howIsTeamLead(MainClass.java:46)
    at com.example.chainedexception.exceptions.MainClass
      .getLeave(MainClass.java:34)
    at com.example.chainedexception.exceptions.MainClass
      .main(MainClass.java:29)
Exception in thread "main" com.example.chainedexception.exceptions.
  NoLeaveGrantedException: Leave not sanctioned.
    at com.example.chainedexception.exceptions.MainClass
      .getLeave(MainClass.java:37)
    at com.example.chainedexception.exceptions.MainClass
      .main(MainClass.java:29)

5.2. Avec chaînage

Ensuite, écrivons un exemple de chaînage de nos exceptions personnalisées:

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.");
    }
}

Enfin, examinons les journaux obtenus avec des exceptions chaînées:

Exception in thread "main" com.example.chainedexception.exceptions
  .NoLeaveGrantedException: Leave not sanctioned.
    at com.example.chainedexception.exceptions.MainClass
      .getLeave(MainClass.java:36)
    at com.example.chainedexception.exceptions.MainClass
      .main(MainClass.java:29)
Caused by: com.example.chainedexception.exceptions
  .TeamLeadUpsetException: Team lead Upset.
    at com.example.chainedexception.exceptions.MainClass
  .howIsTeamLead(MainClass.java:44)
    at com.example.chainedexception.exceptions.MainClass
  .getLeave(MainClass.java:34)
    ... 1 more

Nous pouvons facilement comparer les journaux illustrés et conclure que les exceptions chaînées conduisent à des journaux plus propres.

6. Conclusion

Dans cet article, nous avons examiné le concept des exceptions chaînées.

L'implémentation de tous les exemples peut être trouvée dansthe Github project - il s'agit d'un projet basé sur Maven, il devrait donc être facile à importer et à exécuter tel quel.