80 votes

Lancements ou try+catch

Quelle est la règle générale à suivre pour décider s'il faut ajouter une clause throws à une méthode ou utiliser un try-catch ?

D'après ce que j'ai lu moi-même, les throws doivent être utilisés lorsque l'appelant n'a pas respecté sa part du contrat (objet passé) et les try-catch doivent être utilisés lorsqu'une exception se produit au cours d'une opération effectuée dans la méthode. Est-ce correct ? Si oui, que doit-on faire du côté de l'appelant ?

P.S. : J'ai fait des recherches sur Google et SO mais j'aimerais avoir une réponse claire sur ce point.

6 votes

J'ai toujours été un adepte de l'approche "Si cela a du sens de traiter le problème ici... alors faites-le".

0 votes

J'aime que toutes mes exceptions soient traitées là où elles se produisent, afin de ne pas avoir à les gérer par la suite.

62voto

Bozho Points 273663
  • n'attrapez une exception que si vous pouvez la traiter de manière significative.
  • déclarer le lancement de l'exception vers le haut si elle doit être traitée par le consommateur de la méthode courante
  • lancer des exceptions si elles sont causées par les paramètres d'entrée (mais celles-ci sont le plus souvent non vérifiées)

0 votes

Bien, la troisième règle est très claire. En ce qui concerne le traitement d'une exception de manière significative, est-ce dans les couches supérieures d'un programme ? Cela signifie-t-il que les API ont tendance à lancer généralement des exceptions ? Par ailleurs, dans quels cas une méthode doit-elle relancer les exceptions provenant de sous-méthodes (provenant de méthodes utilitaires privées, par exemple) ?

0 votes

Eh bien, cela dépend énormément. Les API lancent des exceptions, oui. Mais ensuite vient le choix entre vérifié et non vérifié.

3 votes

Pourquoi relancer l'exception ? Il suffit de ne pas l'attraper et de la faire remonter dans la pile d'appels.

15voto

Péter Török Points 72981

En général, une méthode doit lever une exception à l'intention de son appelant lorsqu'elle ne peut pas traiter localement le problème associé. Par exemple, si la méthode est censée lire un fichier dont le chemin d'accès est donné, les exceptions IO ne peuvent pas être traitées localement de manière raisonnable. Il en va de même pour une entrée invalide, en ajoutant que mon choix personnel serait de lancer une exception non vérifiée comme IllegalArgumentException dans ce cas.

Et il devrait attraper une exception d'une méthode appelée si

  • c'est quelque chose qui peut être géré localement (par exemple, essayer de convertir une chaîne de caractères d'entrée en un nombre, et si la conversion échoue, il est tout à fait valable de retourner une valeur par défaut à la place),
  • soit elle ne doit pas être levée (par exemple, si l'exception provient d'une couche inférieure spécifique à l'implémentation, dont les détails d'implémentation ne doivent pas être visibles pour l'appelant - par exemple, je ne veux pas montrer que mon DAO utilise Hibernate pour la persistance de mes entités, donc je récupère toutes les HibernateExceptions localement et les convertit en mes propres types d'exception).

0 votes

Ok. Pour reformuler, une exception serait lancée lorsqu'une solution immédiate n'est pas possible et qu'une certaine interaction est nécessaire "au-dessus" pour décider de ce qu'il faut faire. De même, une exception ne serait pas relancée si elle n'a qu'une "signification" entre un groupe de classes et une exception plus généralisée devrait être lancée à sa place pour informer l'appelant que son attention est requise. Cela vous semble-t-il plus ou moins juste ?

1 votes

@James, plus ou moins :-) Si par "interaction" vous voulez dire demander l'intervention de l'utilisateur, ce n'est pas toujours nécessaire. De même, au lieu de "plus généralisé", je préférerais "différent". Une ConnectionException définie par l'utilisateur n'est pas plus générale qu'une HibernateException.

12voto

Justian Meyer Points 1095

Voici comment je l'utilise :

Les lancers :

  • Vous voulez juste que le code s'arrête quand une erreur se produit.
  • Bon avec des méthodes qui sont sujettes à des erreurs si certaines conditions préalables ne sont ne sont pas remplies.

Try-Catch :

  • Quand vous voulez que le programme se comporte différemment avec différentes erreurs.
  • Idéal si vous voulez fournir significatif des erreurs aux utilisateurs finaux.

Je connais beaucoup de gens qui utilisent toujours les lancers parce que c'est plus propre, mais il n'y a pas autant de contrôle.

0 votes

Vous ne devriez presque JAMAIS utiliser la gestion des exceptions pour le contrôle du programme. C'est une pratique terrible.

2 votes

Il y a aussi Try-catch-rethrow, ou try-catch-wrap-throw - c'est-à-dire que ce n'est pas parce que vous pouvez traiter l'exception de manière significative que vous avez terminé. La méthode doit faire ce que son nom indique qu'elle va faire, ou doit lever une exception : abstractions-r-us.blogspot.com/2010/06/ . (publicité éhontée pour mon blog)

1 votes

C'est une question que je me pose depuis un certain temps. Je pense que j'essaie et utilise des blocs try-catch si nécessaire avec des exceptions définies par l'utilisateur. Exception. Mais je dois dire qu'un throws dans le stub de la méthode est beaucoup plus propre et beaucoup moins de code à trier plus tard si vous devez faire du débogage. Si vous utilisez un throws dans le stub de la méthode, vous devez piéger l'erreur en amont de la chaîne de méthodes, je pense, ce dont je ne suis pas sûr. Avec un try-catch, vous pouvez simplement faire en sorte que le try-catch attrape l'erreur sans avoir à la faire remonter dans la chaîne des méthodes. Je ne suis pas tout à fait sûr de cela, mais je pense que

9voto

Riduidel Points 13456

Ma règle d'or personnelle pour cela est simple :

  • Puis-je le supporter ? d'une manière significative (ajouté à partir du commentaire) ? Donc mettre le code dans try/catch . Par gérer, j'entends pouvoir informer l'utilisateur/récupérer l'erreur ou, dans un sens plus large, être capable de comprendre comment cette exception affecte l'exécution de mon code.
  • Ailleurs, jetez-le

Note : cette réponse est maintenant un wiki communautaire, n'hésitez pas à y ajouter des informations supplémentaires.

6 votes

Puis-je le supporter ? d'une manière significative .

2 votes

Quels sont vos critères pour décider si vous pouvez traiter une exception localement ? Est-ce au niveau où vous pouvez réellement prendre en charge l'exception et afficher un message par exemple ?

0 votes

Le jeter est une mauvaise idée. Le mieux est de le faire passer dans la pile d'appels.

2voto

Alberto Zaccagni Points 11478

Si la méthode où l'exception a été levée dispose d'une quantité suffisante d'informations pour la traiter, elle devrait attraper, générer des informations utiles sur ce qui s'est passé et sur les données traitées.

0 votes

Est-ce que vous écrivez toujours l'exception d'erreur dans un fichier journal ou dans la console. J'y ai pensé hier soir parce que dans le programme réel, vous ne serez pas en mesure de voir la console actuelle, donc vos erreurs ne devraient pas aller dans un fichier texte. Alors comment imprimer e.printStackTrace(). Je vais dans la console lors du débogage mais où d'autre peut-il aller ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X