IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

[Gestion erreurs] Se débarasser des exceptions certifiées : RuntimeException


Sujet :

Java

  1. #1
    Invité
    Invité(e)
    Par défaut [Gestion erreurs] Se débarasser des exceptions certifiées : RuntimeException
    Bonjour,

    Suite à un choix de conception mûrement réfléchi, j'ai décidé de ne laisser aucune exception dans mon code.

    Je me demande comment faire pour intercepter une exception puis simplement lancer une erreur correspondante, en perdant le moins d'informations possible. Pour l'instant je n'utilise qu'une fonction levant une exception et voici comment je l'encapsule :

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
      void sleep(long milliseconds) {
        try {
          Thread.sleep(milliseconds);
        }
        catch (InterruptedException e) {
          throw new Error(e.getMessage());
        }
      }

    D'après la documentation, il y a plein d'autres informations sur une exception "Throwable", notamment un "stack trace", une "cause", une courte description (toString). Je me demande si créer une classe d'erreur pour chaque exception ne sera pas un peu lourd (exemple InterruptedException -> InterruptedError). Quelqu'un à une idée ?
    Dernière modification par Invité ; 07/02/2010 à 14h41. Motif: je met la solution dans le titre du topic

  2. #2
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Citation Envoyé par hellfoust Voir le message
    Suite à un choix de conception mûrement réfléchi, j'ai décidé de ne laisser aucune exception dans mon code.
    Le choix est peut-être un peu extrême. Certaines exceptions peuvent rentrer dans des cas "possibles" où un traitement reste valable

    Citation Envoyé par hellfoust Voir le message
    Je me demande comment faire pour intercepter une exception puis simplement lancer une erreur correspondante, en perdant le moins d'informations possible.
    Il faut bien encapsuler, mais en lui passant carrément l'exception originale car dans ton exemple tu perds plein d'info dont le stacktrace !
    De plus perso j'aurais tendance à préférer une RuntimeException qu'à une Error qui est généralement utilisé par la JVM.
    Pour tout conserver il faut simplement passer l'exception source en "cause", par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    catch (InterruptedException e) {
          throw new RuntimeException(e);
    }
    Ici l'exception sera mis en cause de la RuntimeException, et tu conservera toutes les infos


    Seul défaut : tu as un double-stacktrace, celui du RuntimeException suivi de celui de l'exception originale :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Exception in thread "main" RuntimeException: java.io.IOException: BaDaBoum
    	at ...
    	at ...
    	at ...
    Caused by: java.io.IOException: BaDaBoum
    	at ...
    	at ...
    	at ...
            ... 20 more
    Le problème c'est que si le stacktrace est trop long il peut être tronqué à la fin, et que c'est donc celui de la source qui sera coupé...


    Tu peux éviter cela en ignorant la génération du stacktrace de ton exception, par exemple en te créant ta propre exception de la sorte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class UncheckedException extends RuntimeException {
     
            public UncheckedException(Throwable source) {
                    super(source);
            }
     
            public Throwable fillInStackTrace() {
                    // Cette méthode génère normalement le stacktrace
                    // On ignore cette étape qui ne nous interresse pas
                    // dans le cas précis
                    return this;
            }
    }
    Désormais le stacktrace de ton exception sera vide, et on aura ainsi directement le stacktrace de l'exception source :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Exception in thread "main" UncheckedException: java.io.IOException: BaDaBoum
    Caused by: java.io.IOException: BaDaBoum
    	at ...
    	at ...
    	at ...
    	at ...
    	at ...
    	at ...


    Citation Envoyé par hellfoust Voir le message
    Je me demande si créer une classe d'erreur pour chaque exception ne sera pas un peu lourd (exemple InterruptedException -> InterruptedError). Quelqu'un à une idée ?
    C'est clairement trop lourd !
    Il est préférable d'utiliser une seule et unique exception "englobante".
    Si tu veux récupérer l'exception source tu peux tout simplement utiliser getCause(), voir la remonter en rajoutant une méthode de la sorte dans la classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
            public void reThrow() throws Throwable {
                    throw getCause();
            }
    Ainsi par la suite tu peux faire quelque chose comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    UncheckedException e = ...
    try {
        e.reThrow();
    } catch (IOException e) {
        // c'est une IOException...
    } catch (...)
    Car dupliquer toutes les exceptions risque d'être très lourd et peu pratique pour un intérêt relativement faible...






    Sinon, il existe carrément un moyen de remonter silencieusement n'importe quel exception tel quel, mais c'est un hack pas forcément très propre qui bidouille avec plusieurs éléments du langage, et qui est assez long à expliquer.
    J'ai une ébauche de billet blog là dessus mais je ne sais pas quand j'aurais le temps de finir...


    a++

  3. #3
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 804
    Points
    48 804
    Par défaut
    je rajouterais que l'exemple que tu as donné ext exactement un contre exemple de l'endroit ou il est judicieux de relancer une erreur. Une interruptedException, c'est juste un autre thread qui a demandé au tiens de se réveiller (via l'appel à interrupt()), c'est tout sauf un cas d'erreur et devrais donc etre traité correctement plutot que de renvoyer une error


    Aussi pour le tronquage des stacktraces, il n'y a pas vraiment à s'inquiéter, la jvm ne fait que tronquer l'affichage en supprimant les parties commune du stacktrace entre la cause et l'exception/erreur finale, ca allège l'affichage

  4. #4
    Invité
    Invité(e)
    Par défaut
    Quelle réactivité ! Merci beaucoup pour le tuyau !

    Ta méthode est bien plus propre que ce que j'aurai pu espérer. Je vais faire une classe UncheckedException exactement comme la tienne, sauf que je vais remplacer la signature du constructeur par :

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
      public UncheckedException(Exception source) {

    Car je ne transformerais jamais une Error en UncheckedException, donc pas besoin d'accepter n'importe quelle Throwable en paramètre. Il n'y a pas de problèmes à faire cela ?

    En tout cas merci pour ta réponse de qualité, qui me permet de garder toutes les informations des exceptions (même le statut d'exception), sans avoir à les déclarer

    @tchize_ : Effectivement, c'est pas très futé, mais pour l'instant je laisse ceci en erreur fatale afin de m'en appercevoir si elle arrive lors d'un de mes tests, afin de voir qu'est ce qui pourrait la déclencher. Comme j'utilise la fonction sleep pour séparer deux affichages graphiques, je pourrait me contenter, quand le programme sera fini, d'ignorer cette exception.

  5. #5
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    je rajouterais que l'exemple que tu as donné ext exactement un contre exemple de l'endroit ou il est judicieux de relancer une erreur. Une interruptedException, c'est juste un autre thread qui a demandé au tiens de se réveiller (via l'appel à interrupt()), c'est tout sauf un cas d'erreur et devrais donc etre traité correctement plutot que de renvoyer une error
    Pas forcément... Une InterruptedException survient seulement lorsque le thread reçoit un "interrupt", et dans ce cas il est logique d'arrêter le thread. Donc remonter une exception n'est pas forcément une erreur, à moins que l'on ai mis en place un autre mécanisme pour arrêter le thread.


    Citation Envoyé par hellfoust Voir le message
    Car je ne transformerais jamais une Error en UncheckedException, donc pas besoin d'accepter n'importe quelle Throwable en paramètre. Il n'y a pas de problèmes à faire cela ?
    Je n'y vois aucun problème...

    a++

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [11gR2] Gestion des exceptions/erreurs en PL/SQL
    Par devkais dans le forum PL/SQL
    Réponses: 2
    Dernier message: 05/12/2013, 15h02
  2. [2.x] Personnalité et erreur LDAP (gestion des exceptions)
    Par ray-k dans le forum Symfony
    Réponses: 1
    Dernier message: 19/10/2012, 17h08
  3. Gestion des erreurs et des exceptions en programmation Win32
    Par masterx_goldman dans le forum Windows
    Réponses: 1
    Dernier message: 05/05/2010, 21h35
  4. [POO] Gérer les erreurs MySQL par des exceptions
    Par thepooh dans le forum Langage
    Réponses: 2
    Dernier message: 04/04/2008, 12h16
  5. récupérer les erreurs php dans des exceptions
    Par jeanvincent dans le forum Langage
    Réponses: 6
    Dernier message: 14/10/2005, 17h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo