Partage
  • Partager sur Facebook
  • Partager sur Twitter

Centraliser les exceptions en Java

    22 mai 2009 à 16:01:14

    Bonjour,

    Je suis entrain d'écrire une relativement grosse application en Java, et je ne sais pas trop comment gérer les exceptions.

    En effet, j'aimerais centraliser au maximum les différentes exceptions qui surviennent tout au long de l'application (erreurs sur les flux, les BdD et toutes autres erreurs...). J'aimerais créer un maximum d'erreurs personnalisées qui permettent d'identifier de manière correcte la cause de l'erreur.

    Quelqu'un aurait des idées ou des conseils pour gérer les exceptions de manière correcte, pour les centraliser au maximum ?

    De plus, comment pouvons-nous faire pour que lorsqu'une erreur survient dans une classe fille, celle-ci soit remontée à la classe mère ? (est-ce bien le mot clé throw qu'il faut utiliser) ?
    • Partager sur Facebook
    • Partager sur Twitter
      22 mai 2009 à 16:09:27

      Une Classe par exception personnalisé, il suffit de mettre la classe dans le package le plus adéquat. Pour lever une exception, c'est bien "throw" qu'il faut utiliser.
      • Partager sur Facebook
      • Partager sur Twitter
        22 mai 2009 à 16:14:44

        Pour cenetraliser tes exceptions tu peut:
        - Créer des classes relatives aux différents types d'exception , ces classses hériterons de la classe excpetion.
        - Ainsi tu pourra chaque fois que tu rencontre une anomalie dans une méthode déclencher cette exception.
        - Avec ceci tu pourra catcher les exceptions et ainsi affichés les messages d'erreur correspondant.

        je t'invite a lire ce ptit tuto :exception (Pdf)
        • Partager sur Facebook
        • Partager sur Twitter
        J'ai tous les badges d'OpenClassrooms.
          22 mai 2009 à 17:39:20

          Merci pour les infos, je vais essayer de voir ce que ça donne pour mon appli.
          Je vous tiens au courant lundi
          • Partager sur Facebook
          • Partager sur Twitter
            22 mai 2009 à 18:09:41

            2 pistes, pas forcément adaptées, mais ta question est assez flou (Au moins pour moi ^^ ), donc à toi de voir si ça te convient ou pas :

            - Une classe statique, à laquelle tu envoies des messages lorsqu'une exception est catchée (Sur le principe d'un Logger quelconque : Logger.signalerException(ex)); Ça permet de centraliser les affichages (Que ce soit pour les envoyer vers la console, ou vers une popup Swing, ou vers un fichier de log).

            - Si tu veux remonter les exceptions très haut (Sur plusieurs niveaux), tu peux passer par des RuntimeException. La différence entre une RuntimeException et une exception standard, c'est que tu n'as pas besoin de la relancer à chaque fois. Exemple :

            class Test{
            	void methode1() throws MyException{
            		methode2();
            	}
            	
            	void methode2() throws MyException{
            		methode3();
            	}
            	
            	void methode3() throws MyException{
            		throw new MyException();
            	}
            	
            	public static void main(String[] args){
            		Test test = new Test();
            		try {
            			test.methode1();
            		} catch (MyException ex){
            			MyLogger.signalerErreur(ex);
            		}
            	}
            }
            


            Donc, on voit que pour remonter MyException jusqu'au main, il faut rajouter des throws partout. Pour 1 exception, c'est déjà pas amusant... Si tu dois en plus ajouter throws MyException1, MyException2, MyException3... ça devient vite lourd (Même s'il est possible de factoriser ça avec un "throws Exception", mais c'est moche... Celui qui appelle la méthode ne sait pas à quoi s'attendre).

            Donc, dans ce cas, l'alternative est d'utiliser une RuntimeException :

            class MyException extends RuntimeException{
            ...
            }
            


            L'avantage des RuntimeException, c'est qu'elles n'ont pas besoin d'être "catchées" ou "throwées" (Vive le franglais :p ). Elles remontent donc la pile d'exécution, jusqu'à ce qu'elles tombent dans un catch adapté. Le code résultant, donc, sur l'exemple au dessus, c'est la suppression de tous les "throws MyException".

            Voilà... Si ça t'aide un peu, tant pis, et sinon, tant mieux :p (Ou l'inverse, je sais jamais ^^ )

            Dernière chose : il faut éviter de retarder le catch des erreurs, sauf quand c'est justifié... Parce que plus il intervient tard, plus tu perds de choses (Si ton objectif, c'est de faire planter ton programme mais d'avoir un message d'erreur précis, tu peux catcher dans le main... Si ton objectif, c'est de dire "Votre fichier n'a pas été trouvé, voulez-vous essayer un autre fichier ?", il faut la catcher immédiatement... Et donc éviter les RuntimeException (Et les "throws" en général...)

            Plus le catch est tard, plus t'as un traitement générique (Donc moins de lignes de code), mais moins c'est précis.
            • Partager sur Facebook
            • Partager sur Twitter
              22 mai 2009 à 21:00:29

              JE pense aussi à un truc qui peut dépanner, le handler par défaut qui catch toutes les exceptions.
              ON peut en définir un via Thread.UncaughtExceptionHandler ou un nom qui s'en rapproche... c'est pratique pour envoyer un message d'erreur générique du genre « l'application va fermer car une erreur inattendue est survenue ». Ca permet de faire planter le programme de manière élégante je trouve (plus élégant que un freeze de la GUI ou un access violation de windows)
              • Partager sur Facebook
              • Partager sur Twitter
                23 mai 2009 à 0:53:17

                Je connaissais pas, mais ça revient à peu près au même qu'un try/catch (Exception) dans le main (Sauf que tu peux le déclarer où tu veux, et que ça marche pour tous les threads... Alors que le main ne fait que le thread principal).

                Bref, le principe est le même, mais c'est effectivement plus joli et efficace :)
                • Partager sur Facebook
                • Partager sur Twitter
                  23 mai 2009 à 10:40:07

                  Citation : Veldryn

                  Donc, dans ce cas, l'alternative est d'utiliser une RuntimeException :

                  class MyException extends RuntimeException{
                  ...
                  }
                  



                  L'avantage des RuntimeException, c'est qu'elles n'ont pas besoin d'être "catchées" ou "throwées" (Vive le franglais :p ). Elles remontent donc la pile d'exécution, jusqu'à ce qu'elles tombent dans un catch adapté. Le code résultant, donc, sur l'exemple au dessus, c'est la suppression de tous les "throws MyException".



                  Ou le vilain pas beau. Si tu avais lu la documentation officiel (ou les tutos) sur le site de sun, tu saurais qu'il est super déconseillé d'utiliser des RuntimeException. Eux même le disent, c'est pour les flemmards, mais pas pour du bon code. Il donne les règles (quelques question à répondre) pour savoir si ton exception doit être runtime ou pas, et c'est plutôt rare qu'elle le soit.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    23 mai 2009 à 13:38:55

                    Remarque c'est quand même vachement lourd de mettre un bloc try catch à chaque fois qu'on lit un petit résultat d'une ligne SQl. franchement, ça sert à rien (je parle des getInt, getString, getXXX des ResultSet... pas de l'exécution de la requête elle-même où là c'est effectivement bien justifié)

                    Par analogie, en php les fonctions mysql_fetch_* ne plantent jamais, ou alors il faut faire vraiment exprès.

                    Donc quand on a quelque chose d'aussi chiant à ajouter à chaque fois, je comprends la lassitude des développeurs (moi le premier) qui mettent des catch génériques ou qui utilisent des RuntimeException. Même si effectivement dans un sens strict, c'est pas très bon, c'est moins gavant à écrire et à relire.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      23 mai 2009 à 14:45:14

                      Je ne faisais que donner des pistes de recherche : comme je l'ai précisé, je ne sais pas exactement ce qu'il souhaite faire.

                      Je n'utilise pas moi-même les runtime exception (La seule que j'utilise, c'est UnsupportedOperationException, plus toutes celles définies par Java)

                      Si son souhait est de centraliser les traitements tout en fermant le programme, alors la Runtime exception est la plus adaptée (Mais c'est une façon assez brutale de faire, parce qu'en général, on cherche à éviter que le programme plante, justement). Si son souhait est de gérer les exceptions de manière plus fine, alors le Logger est une bonne solution.

                      Ma préférence va au logger, mais je n'ai pas donné d'avis dans mon message, juste 2 pistes ^^ (Et je n'ai pas lu la doc' de Sun sur les RTE, ça me parait suffisamment évident comme ça :D )
                      • Partager sur Facebook
                      • Partager sur Twitter
                        23 mai 2009 à 17:14:55

                        En fait, je veux uniquement centraliser mes exceptions un maximum au sein de mon application.

                        Je veux de plus, capturer celle-ci au plus près de son apparition de manière à identifier l'erreur de manière précise, enregistrer un message qui corresponde à l'erreur dans un fichier, puis remonter l'exception vers le plus haut niveau de mon application de manière à afficher un message d'erreur à l'utilisateur.
                        • Partager sur Facebook
                        • Partager sur Twitter
                          23 mai 2009 à 21:02:12

                          Dans ce cas, il ne faut pas chercher à la faire "remonter" (Throw / throws / throws), mais la traiter directement dans le catch, via une méthode statique (Donc accessible de n'importe où).

                          Cf le principe du Logger (Qui, comme je le disais, peut être aussi bien un retour vers la sortie standard (System.err.println), vers un fichier de log, ou vers une popup Swing pour ton interface graphique... Voire les 3).

                          L'important, c'est que ce soit 1 seule classe (Pour centraliser), et que tu y renvoies toutes tes exceptions.
                          • Partager sur Facebook
                          • Partager sur Twitter

                          Centraliser les exceptions en Java

                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                          • Editeur
                          • Markdown