Est-ce une mauvaise pratique à attraper Throwable
?
Par exemple quelque chose comme ceci:
try {
// Some code
} catch(Throwable e) {
// handle the exception
}
Est-ce une mauvaise pratique ou devrions-nous être aussi précis que possible?
java
exception-handling
throwable
ktulinho
la source
la source
Réponses:
Vous devez être aussi précis que possible. Sinon, des bugs imprévus pourraient s'éloigner de cette façon.
En outre, les
Throwable
couverturesError
aussi et ce n'est généralement pas un point de retour . Vous ne voulez pas attraper / gérer cela, vous voulez que votre programme meure immédiatement afin que vous puissiez le réparer correctement.la source
C'est une mauvaise idée. En fait, même attraper
Exception
est généralement une mauvaise idée. Prenons un exemple:Maintenant, disons que getUserInput () se bloque pendant un certain temps et qu'un autre thread arrête votre thread de la pire manière possible (il appelle thread.stop ()). Votre bloc catch attrapera une
ThreadDeath
erreur. C'est super mauvais. Le comportement de votre code après avoir détecté cette exception est en grande partie indéfini.Un problème similaire se produit lors de la capture d'Exception. Peut-être a
getUserInput()
échoué en raison d'une InterruptException, ou d'une exception d'autorisation refusée lors de la tentative de journalisation des résultats, ou de toutes sortes d'autres échecs. Vous n'avez aucune idée de ce qui n'a pas fonctionné, car à cause de cela, vous ne savez pas non plus comment résoudre le problème.Vous avez trois meilleures options:
1 - Attrapez exactement la ou les exceptions que vous savez gérer:
2 - Relancez toute exception que vous rencontrez et ne savez pas comment gérer:
3 - Utilisez un bloc finally pour ne pas avoir à vous rappeler de relancer:
la source
throw new Exception("Some additional info, eg. userId " + userId, e);
. Cela sera enregistré dans une belle exception avec 10 causes.Sachez également que lorsque vous attrapez
Throwable
, vous pouvez également attraperInterruptedException
ce qui nécessite un traitement spécial. Pour plus de détails, consultez Traitement de l'exception InterruptedException .Si vous souhaitez uniquement intercepter les exceptions non contrôlées, vous pouvez également envisager ce modèle
De cette façon, lorsque vous modifiez votre code et ajoutez un appel de méthode qui peut lever une exception vérifiée, le compilateur vous le rappellera et vous pourrez ensuite décider quoi faire dans ce cas.
la source
directement à partir du javadoc de la classe Error (qui recommande de ne pas les attraper):
la source
Ce n'est pas une mauvaise pratique si vous ne pouvez absolument pas avoir une bulle d'exception hors d'une méthode.
C'est une mauvaise pratique si vous ne pouvez vraiment pas gérer l'exception. Mieux vaut ajouter des "jets" à la signature de la méthode que simplement attraper et relancer ou, pire, l'envelopper dans une RuntimeException et la relancer.
la source
Throwable
instances - par exemple pour la journalisation des exceptions personnalisée.Catching Throwable est parfois nécessaire si vous utilisez des bibliothèques qui lancent des erreurs avec trop d'enthousiasme, sinon votre bibliothèque peut tuer votre application.
Cependant, il serait préférable dans ces circonstances de ne spécifier que les erreurs spécifiques générées par la bibliothèque, plutôt que tous les Throwables.
la source
Throwable est la classe de base pour toutes les classes qui peuvent être levées (pas seulement les exceptions). Vous ne pouvez pas faire grand-chose si vous attrapez une OutOfMemoryError ou KernelError (voir Quand attraper java.lang.Error? )
attraper des exceptions devrait suffire.
la source
cela dépend de votre logique ou pour être plus spécifique à vos options / possibilités. S'il y a une exception spécifique sur laquelle vous pouvez éventuellement réagir de manière significative, vous pouvez la détecter en premier et le faire.
S'il n'y en a pas et que vous êtes sûr que vous ferez la même chose pour toutes les exceptions et erreurs (par exemple, quitter avec un message d'erreur), alors ce n'est pas un problème pour attraper le jetable.
Habituellement, le premier cas tient et vous n'attraperez pas le jetable. Mais il existe encore de nombreux cas où l'attraper fonctionne bien.
la source
Bien que cela soit décrit comme une très mauvaise pratique, vous pouvez parfois trouver de rares cas où cela est non seulement utile mais également obligatoire. Voici deux exemples.
Dans une application Web où vous devez montrer une page d'erreur complète à l'utilisateur. Ce code s'assure que cela se produit car il s'agit d'un gros
try/catch
autour de tous vos gestionnaires de requêtes (servlets, actions struts ou tout contrôleur ....)}
Comme autre exemple, considérons que vous avez une classe de service qui sert les activités de transfert de fonds. Cette méthode renvoie un
TransferReceipt
si le transfert est effectué ouNULL
s'il n'a pas pu.Maintenant, vous obtenez une image
List
des transferts de fonds de l'utilisateur et vous devez utiliser le service ci-dessus pour les faire tous.Mais que se passera-t-il si une exception se produit? Vous ne devez pas vous arrêter, car un transfert peut avoir été un succès et un autre non, vous devez continuer à travers tous les utilisateurs
List
et afficher le résultat à chaque transfert. Donc, vous vous retrouvez avec ce code.Vous pouvez parcourir de nombreux projets open source pour voir que le
throwable
est vraiment mis en cache et géré. Par exemple, voici une recherche surtomcat
,struts2
etprimefaces
:https://github.com/apache/tomcat/search?utf8=%E2%9C%93&q=catch%28Throwable https://github.com/apache/struts/search?utf8=%E2%9C%93&q=catch % 28Throwable https://github.com/primefaces/primefaces/search?utf8=%E2%9C%93&q=catch%28Throwable
la source
throwable
, c'est sur quoi porte cette questionLa question est un peu vague; demandez-vous "est-il OK pour attraper
Throwable
", ou "est-il OK pour attraperThrowable
et ne rien faire"? Beaucoup de gens ici ont répondu à cette dernière question, mais c'est un problème secondaire; 99% du temps , vous ne devriez pas « consommer » ou rejeter l'exception, si vous attrapezThrowable
ouIOException
ou autre.Si vous propagez l'exception, la réponse (comme la réponse à tant de questions) est "ça dépend". Cela dépend de ce que vous faites à l'exception de la raison pour laquelle vous l'attrapez.
Un bon exemple des raisons pour lesquelles vous voudriez attraper
Throwable
est de fournir une sorte de nettoyage en cas d'erreur. Par exemple dans JDBC, si une erreur se produit pendant une transaction, vous voudrez annuler la transaction:Notez que l'exception n'est pas rejetée, mais propagée.
Mais en
Throwable
règle générale, attraper parce que vous n'avez pas de raison et que vous êtes trop paresseux pour voir quelles exceptions spécifiques sont lancées est une mauvaise forme et une mauvaise idée.la source
De manière générale, vous voulez éviter d'attraper des
Error
s mais je peux penser à (au moins) deux cas spécifiques où il convient de le faire:AssertionError
ce qui est par ailleurs inoffensif.la source
Si nous utilisons throwable , cela couvre également Error et c'est tout.
Exemple.
}
Production:
la source
Throwable est la superclasse de toutes les erreurs et excétions. Si vous utilisez Throwable dans une clause catch, il détectera non seulement toutes les exceptions, mais également toutes les erreurs. Des erreurs sont émises par la JVM pour indiquer des problèmes graves qui ne sont pas destinés à être traités par une application. Des exemples typiques pour cela sont OutOfMemoryError ou StackOverflowError. Les deux sont causés par des situations qui sont hors du contrôle de l'application et ne peuvent pas être gérées. Donc, vous ne devriez pas attraper Throwables à moins que vous ne soyez convaincu que ce ne sera qu'une exception résidant dans Throwable.
la source
Bien qu'il soit généralement une mauvaise pratique d'attraper Throwable (comme le montrent les nombreuses réponses à cette question), les scénarios où la capture
Throwable
est utile sont assez courants. Permettez-moi de vous expliquer un cas que j'utilise dans mon travail, avec un exemple simplifié.Considérez une méthode qui effectue l'ajout de deux nombres, et après l'ajout réussi, elle envoie une alerte par e-mail à certaines personnes. Supposons que le nombre retourné est important et utilisé par la méthode appelante.
Le code pour envoyer des alertes par e-mail lit un grand nombre de configurations système et, par conséquent, il peut y avoir une variété d'exceptions lancées à partir de ce bloc de code. Mais nous ne voulons pas qu'une exception rencontrée lors de l'envoi d'alertes se propage à la méthode de l'appelant, car cette méthode est simplement concernée par la somme des deux valeurs Integer qu'elle fournit. Par conséquent, le code pour envoyer les alertes par e-mail est placé dans un
try-catch
bloc, oùThrowable
est intercepté et toutes les exceptions sont simplement enregistrées, ce qui permet au reste du flux de continuer.la source
Exception
s par tous les moyens, mais pasThrowable
.