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

avec Java Discussion :

Exception / Log / Bonne pratique


Sujet :

avec Java

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Août 2007
    Messages
    165
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 165
    Points : 116
    Points
    116
    Par défaut Exception / Log / Bonne pratique
    Bonjour,

    je continue le tour des sujets qui me posent problème, et pour lesquels je n'ai pas forcément bien compris les bonnes pratiques.

    Aujourd'hui, j'ai un problème avec les exceptions couplées à un logger.

    J'ai lu cet article fort intéressant, mais cela ne répond pas forcément à mes interrogations :

    http://anisfrikha.developpez.com/tut...xceptions/#LVI

    Imaginons une classe, dans laquelle une méthode en appelle une autre d'une autre class, elle même appelant une 3ème méthode d'une 3ème class.

    En gros F1->F2->F3.

    Quelle est la bonne manière d'opérer pour logger ce qu'il faut, et bien remonter les exceptions ?

    Je m'explique, actuellement je vois ce genre de pratique dans le projet :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    public void F1();
    {
        try {
            F2();
            .....
        } catch (Exception ex) {
            Log.error("message 1", ex);
        }
    }
     
    public void F2();
    {
        try {
            F3();
            .....
        } catch (Exception ex) {
            Log.error("message 2", ex);
            Throw ex;
        }
    }
     
    public void F3();
    {
        try {
            .....
        } catch (Exception ex) {
            Log.error("message 3", ex);
            Throw ex;
        }
    }
    Est ce normal finalement pour une exception générée dans F3 d'avoir finalement 3 écritures dans le log ?
    Serait il plus judicieux de virer les appels aux Log dans F2 et F3 ? je présume que non car F2 peut parfaitement planter pour du code autre que l'appel à F3...
    Devrait on remplacer les bloc try...catch par un throws global sur la méthode pour F2 et F3 ?

    Bref me conseillez vous ?

    Par avance merci.

  2. #2
    Membre averti

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2010
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2010
    Messages : 246
    Points : 402
    Points
    402
    Par défaut
    Ce que je te conseil est d'adapter les Exceptions aux différentes méthodes si tu le souhaite. Ensuite, ne faire que un seul "try catch" au niveau le plus haut.

    En gros :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
     
    public void F1() throw F1Exception{
        ...
    }
     
    public void F2() throw F2Exception{
        ...
    }
     
    public void F3() throw F3Exception{
        ...
    }
    Et plus loin dans ton main (ou là ou tu appelera la méthode F1()) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    try{
    F1();
    catch(F3Exception e){
        ....
    }
    catch(F2Exception e){
        ....
    }
    catch(F1Exception e){
        ....
    }
    Après à toi de définir les erreur FXException, et savoir quand chaque méthode doit la lancer, ainsi que le traitement associé.
    C'est en aidant les autres qu'on en apprend beaucoup soi-même

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Août 2007
    Messages
    165
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 165
    Points : 116
    Points
    116
    Par défaut
    Oui j'y pensais à cette solution, sauf que c'est toujours le même type d'exception qui est remonté.....et que je n'ai point le temps, ni vraiment la possibilité de définir un type spécifique d'exception.

    Si je gère le log au niveau le plus haut et qu'une exception est issue d'un niveau inférieur, est ce que le logger conservera une trace d'où a été générée l'exception ?

  4. #4
    Membre averti

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2010
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2010
    Messages : 246
    Points : 402
    Points
    402
    Par défaut
    le logger je ne sais pas, par contre tu peux faire afficher la stack dans ton log via la méthode "printStackTrace()"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    catch (Exception e) {
            e.printStackTrace();
        }
    après tu peux faire écrire son contenu dans ton Log si tu le souhaite. Et la tu auras la pile d'appel complète, donc tu sauras d'où est partie l'exception.
    C'est en aidant les autres qu'on en apprend beaucoup soi-même

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Août 2007
    Messages
    165
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 165
    Points : 116
    Points
    116
    Par défaut
    Oui justement, je fais des appels du style

    Log.error(String message, Throwable t)

    Mais ce qui m'inquiète c'est de savoir comment la pile sera constituée si je le fais au plus haut niveau.
    Je voudrais que si l'exception est générée au niveau le plus bas avoir une seule trace dans le log, et avoir une pile d'appel précise.

  6. #6
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 074
    Points : 7 978
    Points
    7 978
    Par défaut
    Normalement tu devrais remontrer jusqu'ou l'exception a été throw dés le depart.

    Donc logguer a la base et pas dans les branches me semblerait mieux ... mais bon c'est mon avis.

    Edit : T'as edité entretemps, mais sinon le mieux c'est d'essayer je pense pour etre sure et etre fixé.
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre expert

    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2004
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 301
    Points : 3 675
    Points
    3 675
    Par défaut
    Hello,

    moi je loggerais partout, et n'activerais le log que dans les classes que l'on souhaite monitorer. Il est normal pour une classe X de produire du log en cas d'exception, même si cette exception est propagée plus loin. Il ne faut pas préjuger de qui utilisera une classe.

    Dans ton cas, tu as F1->F2->F3, mais rien ne garantit que demain, tu n'auras pas F4->F5->F3. Si tu ne log qu'au niveau de F1, alors demain tu n'auras plus de log même que tu as eu une exception dans F3.....

    Après, rien n'est rigide, rien n'est figé. Et certains cas d'utilisation se justifient à 100% de ne PAS avoir de log du tout. Mais il faut toujours penser à ce qu'il se passera lorsque l'on changera le comportement / enrichira l'application.

    "Le plug gros problème des citations trouvées sur internet, c'est qu'on ne peut jamais garantir leur authenticité"

    Confucius, 448 av. J-C

  8. #8
    Membre confirmé Avatar de Mobius
    Profil pro
    none
    Inscrit en
    Avril 2005
    Messages
    463
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : none

    Informations forums :
    Inscription : Avril 2005
    Messages : 463
    Points : 558
    Points
    558
    Par défaut
    Apparement chacun a sa bonne pratique.

    Un jour (pas si lointain) j'ai lu un article qui indiquait de logger les erreurs si on ne les propagait pas et de ne pas les logger si elle sont propagée ou encapsulé dans une autre exception qui est propagée.

    Cela permet :
    - de savoir ou s'est produit l'erreur exactement (avec des lignes du style "cause by ..." si l'erreur est encapsulé dans une autre exception puis propagé).
    - de ne pas avoir plusieurs stack pour la même erreur (c'est le cas si tu log l'erreur a plusieurs niveaux)
    Librairie d'accès LDAP en Java : LdapBeans
    et pensez au tag

  9. #9
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 074
    Points : 7 978
    Points
    7 978
    Par défaut
    Oui vous n'avez pas tort.
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Août 2007
    Messages
    165
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 165
    Points : 116
    Points
    116
    Par défaut
    Intéressant, mais j'ai besoin d'exemple pratique pour mieux appréhender tout cela car quelque part finalement le commentaire de Mobius s'oppose un peu à Pill_S :p

  11. #11
    Membre expert

    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2004
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 301
    Points : 3 675
    Points
    3 675
    Par défaut
    La logique de Mobius se défend également très bien. Comme je l'ai dit il n'y a pas de règle absolue, le pire étant de ne pas logger bien sûr...
    "Le plug gros problème des citations trouvées sur internet, c'est qu'on ne peut jamais garantir leur authenticité"

    Confucius, 448 av. J-C

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Août 2007
    Messages
    165
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 165
    Points : 116
    Points
    116
    Par défaut
    Ne pas logger est "mal" :p mais perso je déteste aussi avoir un gros pavé dans le log totalement illisible.
    C'est dur de trouver quelque chose quand c'est noyé dans des km de texte.

    Et j'avoue que ce n'est pas évident d'avoir un juste milieu :p

  13. #13
    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,

    Perso j'évite au maximum de logger les erreurs dans les try/catch... Je préfère laisser remonter les erreurs...

    Pour moi il y a deux cas distincts :
    • L'exception peut survenir lors d'un déroulement normale du programme, et on peut donc mettre en place une solution de contournement.
      Dans ce cas le catch sert à mettre en place cette solution de contournement.
      Exemple : Une saisie utilisateur invalide provoque un NumberFormatException et on lui demande de ressaisir la valeur.
      Généralement il n'est pas vraiment utile de logguer ces exceptions là...

    • L'exception ne devrait pas dans le déroulement normal du programme. C'est par exemple le cas des accès I/O sur des ressources qui devraient exister, etc.
      :arrow Il est très important de logguer ces erreurs et de remonter le problème immédiatement en interrompant le processus.

      Pour moi on ne doit pas se contenter de logguer cela comme ceci :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      catch (Exception e) {
          e.printStackTrace(); // ou autre système de log
      }
      Car cela signifie qu'on va logguer et continuer notre traitement "comme si de rien n'était". L'utilisateur ne sera pas averti du problème !
      On bien souvent cela provoque d'autres erreurs par la suite, parfois beaucoup plus loin dans le code, ce qui pourrait engendrer une multitude d'erreur plus ou moins lié et plus ou moins difficile à comprendre.


    Pour moi il est préférable de laisser remonter l'exception (et donc ne pas faire de catch) ou de l'englober dans une RuntimeException si on ne vaut pas avoir à se la trainer tout au long du programme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    catch (IOException e) {
        // Cette IOException ne devrait pas survenir,
        // mais on la remonte quand même au cas où,
        // englobé dans une unchecked-exception afin
        // de ne pas avoir à la traiter tout le temps...
        throw new RuntimeException("info erreur", e);
    }

    L'intérêt c'est que si une erreur inattendu survient, par défaut elle va remonter la pile d'appel et planter le programme, mais avec une stacktrace utile au debbugage.


    Après bien sûr on peut mettre en place un mécanisme pour éviter de planter méchamment en affichant un "joli" message d'erreur voir en remontant automatiquement un "bug-report".
    Il y a divers moyens pour cela, comme par exemple en utilisant un UncaughtExceptionHandler...


    a++

  14. #14
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 074
    Points : 7 978
    Points
    7 978
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    catch (IOException e) {
        // Cette IOException ne devrait pas survenir,
        // mais on la remonte quand même au cas où,
        // englobé dans une unchecked-exception afin
        // de ne pas avoir à la traiter tout le temps...
        throw new RuntimeException("info erreur", e);
    }
    Mmmm je n'avais jamais pensé a ca tiens ... intéressant.
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  15. #15
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Janvier 2012
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2012
    Messages : 16
    Points : 11
    Points
    11
    Par défaut
    Personnellement, j'ai travaillé sur un projet pas mal fait sur ce point.
    Avec spring, ils ont fait un bel AOP sur tout le package "services".
    En clair toutes les classes d’implémentation de Service étaientt wrappées par Spring AOP.
    Conclusion :
    Un wrapper lance la méthode du service et gère le try catch et la log (arguments méthodes, exception).
    Comme ça c'est camoufler, généraliser sans polluer le code qui contient le flux normal d’exécution.

    Beau boulot

    EDIT : et sans oublier que l'on peut toujours rajouter de la log dans l'implém avec un loggerFactory si l'on souhaite.

Discussions similaires

  1. Réponses: 31
    Dernier message: 01/08/2014, 16h53
  2. Bonnes pratiques de protections individuelles
    Par Community Management dans le forum Sécurité
    Réponses: 22
    Dernier message: 05/04/2013, 11h47
  3. Réponses: 4
    Dernier message: 02/02/2010, 23h49
  4. [Débutant] Bonnes pratiques avec les exceptions
    Par scougirou dans le forum Langage
    Réponses: 1
    Dernier message: 08/08/2007, 19h18

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