Quand choisir les exceptions cochées et non vérifiées

En Java (ou tout autre langage avec des exceptions vérifiées), lors de la création de votre propre classe d’exception, comment décidez-vous si elle doit être cochée ou non?

Mon instinct est de dire qu’une exception vérifiée serait appelée dans les cas où l’appelant pourrait être capable de récupérer de manière productive, où une exception non vérifiée serait plus pour les cas irrécupérables, mais je serais intéressé par les pensées des autres.

Les exceptions vérifiées sont excellentes, à condition que vous compreniez à quel moment elles doivent être utilisées. L’API Java Core ne respecte pas ces règles pour SQLException (et parfois pour IOException), raison pour laquelle elles sont si terribles.

Les exceptions vérifiées doivent être utilisées pour les erreurs prévisibles mais non préjudiciables sur lesquelles il est raisonnable de se remettre .

Les exceptions non vérifiées doivent être utilisées pour tout le rest.

Je vais vous expliquer cela car la plupart des gens ne comprennent pas ce que cela signifie.

  1. Prévisible, mais impossible à prévenir : l’appelant a fait tout ce qui était en son pouvoir pour valider les parameters d’entrée, mais certaines conditions hors de leur contrôle ont entraîné l’échec de l’opération. Par exemple, vous essayez de lire un fichier, mais quelqu’un le supprime entre le moment où vous vérifiez s’il existe et le moment où l’opération de lecture commence. En déclarant une exception vérifiée, vous indiquez à l’appelant d’anticiper cet échec.
  2. Raisonnable de récupérer : Il est inutile de dire aux appelants d’anticiper les exceptions qu’ils ne peuvent pas récupérer. Si un utilisateur tente de lire à partir d’un fichier non existant, l’appelant peut lui demander un nouveau nom de fichier. D’autre part, si la méthode échoue à cause d’un bogue de programmation (arguments de méthode non valides ou implémentation de méthode boguée), l’application ne peut rien faire pour résoudre le problème en cours d’exécution. La meilleure chose à faire est de consigner le problème et d’attendre que le développeur le répare ultérieurement.

À moins que l’exception que vous lancez remplisse toutes les conditions ci-dessus, elle doit utiliser une exception non vérifiée.

Réévaluer à tous les niveaux : Parfois, la méthode qui détecte l’exception vérifiée n’est pas le bon endroit pour gérer l’erreur. Dans ce cas, considérez ce qui est raisonnable pour vos propres appelants. Si l’exception est prévisible, impossible à prévenir et raisonnable pour eux, vous devriez lancer une exception vérifiée vous-même. Sinon, vous devez envelopper l’exception dans une exception non vérifiée. Si vous suivez cette règle, vous vous retrouverez à convertir des exceptions vérifiées en exceptions non vérifiées et inversement, selon la couche dans laquelle vous vous trouvez.

Pour les exceptions cochées et non vérifiées, utilisez le bon niveau d’abstraction . Par exemple, un référentiel de codes avec deux implémentations différentes (firebase database et système de fichiers) devrait éviter d’exposer des détails spécifiques à l’implémentation en lançant SQLException ou IOException . Au lieu de cela, il devrait envelopper l’exception dans une abstraction qui couvre toutes les implémentations (par exemple, RepositoryException ).

D’ un apprenant Java :

Lorsqu’une exception se produit, vous devez soit attraper et gérer l’exception, soit indiquer au compilateur que vous ne pouvez pas le gérer en déclarant que votre méthode lève cette exception, le code qui utilise votre méthode devra alors gérer cette exception (même peut également choisir de déclarer qu’il lève l’exception s’il ne peut pas le gérer).

Le compilateur vérifiera que nous avons fait l’une des deux choses (attraper ou déclarer). Donc, ils sont appelés exceptions vérifiées. Mais les erreurs et les exceptions d’exécution ne sont pas vérifiées par le compilateur (même si vous pouvez choisir d’attraper ou de déclarer, il n’est pas obligatoire). Donc, ces deux sont appelés exceptions non vérifiées.

Les erreurs sont utilisées pour représenter les conditions qui se produisent en dehors de l’application, telles que le blocage du système. Les exceptions d’exécution se produisent généralement par erreur dans la logique de l’application. Vous ne pouvez rien faire dans ces situations. Lorsque l’exception d’exécution se produit, vous devez réécrire votre code de programme. Donc, ceux-ci ne sont pas vérifiés par le compilateur. Ces exceptions d’exécution seront découvertes lors du développement et de la période de test. Ensuite, nous devons refactoriser notre code pour supprimer ces erreurs.

La règle que j’utilise est: n’utilisez jamais d’exceptions non vérifiées! (ou quand vous ne voyez aucun moyen de le contourner)

Il y a un argument très fort pour le contraire: ne jamais utiliser les exceptions cochées. Je suis réticent à prendre parti dans le débat, mais il semble y avoir un large consensus sur le fait que l’introduction d’exceptions vérifiées était une mauvaise décision après coup. Veuillez ne pas tirer sur le messager et vous référer à ces arguments .

Sur tout système suffisamment grand, avec de nombreuses couches, les exceptions vérifiées sont inutiles car, de toute façon, vous avez besoin d’une stratégie au niveau architectural pour gérer la façon dont l’exception sera traitée (utilisez une barrière de sécurité)

Avec les exceptions vérifiées, votre stratégie de gestion des erreurs est micro-gérée et insupportable sur tous les grands systèmes.

La plupart du temps, vous ne savez pas si une erreur est “récupérable” car vous ne savez pas dans quelle couche se trouve l’appelant de votre API.

Disons que je crée une API SsortingngToInt qui convertit la représentation sous forme de chaîne d’un entier en un Int. Dois-je lancer une exception vérifiée si l’API est appelée avec la chaîne “foo”? Est-ce récupérable? Je ne sais pas parce que dans sa couche l’appelant de mon API SsortingngToInt a peut-être déjà validé l’entrée, et si cette exception est levée, c’est soit un bogue, soit une corruption de données et elle n’est pas récupérable pour cette couche.

Dans ce cas, l’appelant de l’API ne veut pas intercepter l’exception. Il veut seulement laisser l’exception “bouillonner”. Si j’ai choisi une exception vérifiée, cet appel aura beaucoup de bloc catch inutile pour renvoyer artificiellement l’exception.

Ce qui est récupérable dépend le plus souvent de l’appelant de l’API, et non de l’écrivain de l’API. Une API ne doit pas utiliser les exceptions vérifiées, car seules les exceptions non vérifiées permettent de choisir de capturer ou d’ignorer une exception.

Tu as raison.

Les exceptions non vérifiées permettent au système de tomber en panne rapidement, ce qui est une bonne chose. Vous devez indiquer clairement quelle est votre méthode pour fonctionner correctement. De cette façon, vous ne pouvez valider l’entrée qu’une seule fois.

Par exemple:

 /** * @params operation - The operation to execute. * @throws IllegalArgumentException if the operation is "exit" */ public final void execute( Ssortingng operation ) { if( "exit".equals(operation)){ throw new IllegalArgumentException("I told you not to..."); } this.operation = operation; ..... } private void secretCode(){ // we perform the operation. // at this point the opreation was validated already. // so we don't worry that operation is "exit" ..... } 

Juste pour donner un exemple. Le fait est que si le système échoue rapidement, vous saurez où et pourquoi il a échoué. Vous aurez un stacktrace comme:

  IllegalArgumentException: I told you not to use "exit" at some.package.AClass.execute(Aclass.java:5) at otherPackage.Otherlass.delegateTheWork(OtherClass.java:4569) ar ...... 

Et vous saurez ce qui s’est passé. La classe OtherClass dans la méthode “delegateTheWork” (à la ligne 4569) a appelé votre classe avec la valeur “exit”, même si elle ne devait pas, etc.

Sinon, vous devrez saupoudrer des validations sur tout votre code, ce qui est source d’erreurs. De plus, il est parfois difficile de savoir ce qui a mal tourné et vous pouvez vous attendre à des heures de débogage frustrant.

La même chose se produit avec NullPointerExceptions. Si vous avez une classe de 700 lignes avec 15 méthodes, qui utilise 30 atsortingbuts et qu’aucune d’entre elles ne peut être nulle, au lieu de valider la nullité dans chacune de ces méthodes, vous pouvez les rendre en lecture seule et les valider dans le constructeur ou méthode d’usine.

  public static MyClass createInstane( Object data1, Object data2 /* etc */ ){ if( data1 == null ){ throw NullPointerException( "data1 cannot be null"); } } // the rest of the methods don't validate data1 anymore. public void method1(){ // don't worry, nothing is null .... } public void method2(){ // don't worry, nothing is null .... } public void method3(){ // don't worry, nothing is null .... } 

Exceptions vérifiées Utiles lorsque le programmeur (vous ou vos collègues) a tout fait correctement, validé l’entrée, exécuté des tests et que tout le code est parfait, mais que le code se connecte à un service Web tiers (ou à un fichier). vous utilisiez a été supprimé par un autre processus externe, etc.). Le service Web peut même être validé avant la tentative de connexion, mais pendant le transfert de données, quelque chose a mal tourné.

Dans ce scénario, vous ou vos collègues ne pouvez rien faire pour l’aider. Mais vous devez quand même faire quelque chose et ne pas laisser l’application mourir et disparaître aux yeux de l’utilisateur. Vous utilisez une exception vérifiée pour cela et gérez l’exception, que pouvez-vous faire quand cela se produit?, La plupart du temps, juste pour tenter de consigner l’erreur, probablement enregistrer votre travail (l’application fonctionne) et présenter un message à l’utilisateur . (Le site blabla est en panne, veuillez réessayer plus tard, etc.)

Si l’exception vérifiée est surutilisée (en ajoutant “Exception de lancement” dans toutes les signatures de méthodes), votre code deviendra très fragile, car tout le monde ignorera cette exception (car elle est trop générale) et la qualité du code sera sérieuse. compromis.

Si vous abusez d’une exception non vérifiée, quelque chose de similaire se produira. Les utilisateurs de ce code ne savent pas si quelque chose ne va pas, une grande partie de try {…} catch (Throwable t) apparaîtra.

Voici ma «règle de base».
J’utilise:

  • exception non vérifiée dans le code de ma méthode pour un échec dû à l’appelant (qui implique une documentation explicite et complète )
  • exception vérifiée pour un échec dû à l’ appelé que je dois rendre explicite à toute personne souhaitant utiliser mon code

Comparé à la réponse précédente, il s’agit d’une justification claire (sur laquelle on peut être d’accord ou d’accord) pour l’utilisation de l’un ou l’autre (ou des deux) types d’exceptions.


Pour ces deux exceptions, je créerai ma propre exception non vérifiée et vérifiée pour mon application (une bonne pratique, comme mentionné ici ), à l’exception des exceptions non vérifiées très courantes (comme NullPointerException).

Ainsi, par exemple, le but de cette fonction particulière ci-dessous est de faire (ou d’obtenir si existe déjà) un object,
sens:

  • le conteneur de l’object à faire / obtenir DOIT exister (responsabilité de l’appelant
    => exception non vérifiée ET effacer le commentaire javadoc pour cette fonction appelée)
  • les autres parameters ne peuvent pas être nuls
    (choix du codeur pour le mettre sur le CALLER: le codeur ne vérifiera pas de paramètre nul mais le codeur le documente)
  • le résultat ne peut pas être nul
    (responsabilité et choix du code de l’appelé, choix qui sera d’un grand intérêt pour l’appelant
    => vérifié exception car chaque appelant DOIT prendre une décision si l’object ne peut pas être créé / trouvé, et cette décision doit être appliquée au moment de la compilation: ils ne peuvent pas utiliser cette fonction sans avoir à gérer cette possibilité exception).

Exemple:


 /** * Build a folder. 
* Folder located under a Parent Folder (either RootFolder or an existing Folder) * @param aFolderName name of folder * @param aPVob project vob containing folder (MUST NOT BE NULL) * @param aParent parent folder containing folder * (MUST NOT BE NULL, MUST BE IN THE SAME PVOB than aPvob) * @param aComment comment for folder (MUST NOT BE NULL) * @return a new folder or an existing one * @throws CCException if any problems occurs during folder creation * @throws AssertionFailedException if aParent is not in the same PVob * @throws NullPointerException if aPVob or aParent or aComment is null */ static public Folder makeOrGetFolder(final Ssortingng aFoldername, final Folder aParent, final IPVob aPVob, final Comment aComment) throws CCException { Folder aFolderRes = null; if (aPVob.equals(aParent.getPVob() == false) { // UNCHECKED EXCEPTION because the caller failed to live up // to the documented entry criteria for this function Assert.isLegal(false, "parent Folder must be in the same PVob than " + aPVob); } final Ssortingng ctcmd = "mkfolder " + aComment.getCommentOption() + " -in " + getPNameFromRepoObject(aParent) + " " + aPVob.getFullName(aFolderName); final Status st = getCleartool().executeCmd(ctcmd); if (st.status || SsortingngUtils.ssortingctContains(st.message,"already exists.")) { aFolderRes = Folder.getFolder(aFolderName, aPVob); } else { // CHECKED EXCEPTION because the callee failed to respect his contract throw new CCException.Error("Unable to make/get folder '" + aFolderName + "'"); } return aFolderRes; }

Ce n’est pas seulement une question de capacité à récupérer de l’exception. Ce qui importe le plus, à mon avis, c’est de savoir si l’appelant est intéressé ou non par une exception.

Si vous écrivez une bibliothèque à utiliser ailleurs ou une couche de niveau inférieur dans votre application, demandez-vous si l’appelant souhaite intercepter (connaître) votre exception. S’il ne l’est pas, alors utilisez une exception non vérifiée pour ne pas le surcharger inutilement.

C’est la philosophie utilisée par de nombreux frameworks. On pense en particulier au spring et à la mise en veille prolongée – ils convertissent précisément les exceptions vérifiées connues en exceptions non vérifiées, car les exceptions vérifiées sont trop utilisées en Java. Un exemple auquel je peux penser est l’exception JSONException de json.org, qui est une exception vérifiée et qui est la plupart du temps agaçante – elle doit être décochée, mais le développeur n’a tout simplement pas réfléchi.

Soit dit en passant, la plupart du temps, l’intérêt de l’appelant pour l’exception est directement lié à la possibilité de récupérer de l’exception, mais ce n’est pas toujours le cas.

Vous pouvez l’appeler une exception cochée ou non vérifiée; cependant, les deux types d’exception peuvent être interceptés par le programmeur. La meilleure réponse est donc: écrivez toutes vos exceptions sans les contrôler et documentez-les. De cette façon, le développeur qui utilise votre API peut choisir d’accepter ou non cette exception et de faire quelque chose. Les exceptions vérifiées sont une perte de temps pour tout le monde et rendent votre code un cauchemar choquant à regarder. Les tests unitaires appropriés vous indiqueront toutes les exceptions que vous pourriez avoir à prendre et à faire.

Voici une solution très simple à votre dilemme vérifié / non vérifié.

Règle 1: pensez à une exception non vérifiée en tant que condition testable avant l’exécution du code. par exemple…

 x.doSomething(); // the code throws a NullPointerException 

où x est nul … le code devrait avoir les éléments suivants…

 if (x==null) { //do something below to make sure when x.doSomething() is executed, it won't throw a NullPointerException. x = new X(); } x.doSomething(); 

Règle 2: Considérez une exception vérifiée comme une condition non testable pouvant survenir pendant l’exécution du code.

 Socket s = new Socket(“google.com”, 80); InputStream in = s.getInputStream(); OutputStream out = s.getOutputStream(); 

… Dans l’exemple ci-dessus, l’URL (google.com) peut ne pas être disponible en raison d’une panne du serveur DNS. Même au moment où le serveur DNS fonctionnait et résolvait le nom «google.com» en une adresse IP, si la connexion était établie avec google.com, à tout moment après-mot, le réseau pourrait tomber en panne. Vous ne pouvez simplement pas tester le réseau tout le temps avant de lire et d’écrire sur des stream.

Il y a des moments où le code doit simplement être exécuté avant que nous puissions savoir s’il y a un problème. En forçant les développeurs à écrire leur code de manière à les forcer à gérer ces situations via Checked Exception, je dois montrer mon chapeau au créateur de Java qui a inventé ce concept.

En général, presque toutes les API en Java suivent les 2 règles ci-dessus. Si vous essayez d’écrire dans un fichier, le disque pourrait se remplir avant de terminer l’écriture. Il est possible que d’autres processus aient provoqué la saturation du disque. Il n’y a tout simplement aucun moyen de tester cette situation. Pour ceux qui interagissent avec le matériel, à tout moment, l’utilisation du matériel peut échouer, les exceptions vérifiées semblent constituer une solution élégante à ce problème.

Il y a une zone grise à cela. Dans le cas où de nombreux tests sont nécessaires (une instruction hallucinante avec beaucoup de && et ||), l’exception déclenchée sera une exception CheckedException, simplement parce que c’est trop pénible pour réussir – vous ne pouvez tout simplement pas dire ce problème est une erreur de programmation. S’il y a beaucoup moins de 10 tests (par exemple “if (x == null)”), alors l’erreur du programmeur devrait être une exception UncheckedException.

Les choses deviennent intéressantes quand on traite avec des interprètes de langue. Selon les règles ci-dessus, une erreur de syntaxe doit-elle être considérée comme une exception cochée ou non vérifiée? Je dirais que si la syntaxe du langage peut être testée avant d’être exécutée, cela devrait être une exception UncheckedException. Si la langue ne peut pas être testée – de la même manière que le code d’assemblage s’exécute sur un ordinateur personnel, alors l’erreur de syntaxe doit être une exception vérifiée.

Les 2 règles ci-dessus suppriment probablement 90% de vos préoccupations. Pour résumer les règles, suivez ce schéma… 1) si le code à exécuter peut être testé avant d’être exécuté pour qu’il s’exécute correctement et si une exception se produit – autrement dit une erreur de programmeur, l’exception doit être une exception UncheckedException (une sous-classe de RuntimeException) ). 2) si le code à exécuter ne peut pas être testé avant d’être exécuté pour qu’il s’exécute correctement, l’exception doit être une exception vérifiée (une sous-classe d’exception).

Exception vérifiée: Si le client peut récupérer à partir d’une exception et souhaite continuer, utilisez l’exception vérifiée.

Exception non contrôlée : si un client ne peut rien faire après l’exception, déclenchez une exception non vérifiée.

Exemple: si vous devez effectuer une opération arithmétique dans une méthode A () et en fonction de la sortie de A (), vous devez effectuer une autre opération. Si la sortie est nulle à partir de la méthode A () à laquelle vous ne vous attendez pas pendant l’exécution, vous devez alors lancer une exception de pointeur Null, qui est une exception à l’exécution.

Se référer ici

Je suis d’accord avec la préférence pour les exceptions non vérifiées, en particulier lors de la conception d’une API. L’appelant peut toujours choisir d’attraper une exception non contrôlée et documentée. Vous ne forcez pas inutilement l’appelant.

Je trouve les exceptions vérifiées utiles au niveau inférieur, comme détail d’implémentation. Cela semble souvent être un meilleur mécanisme de contrôle que de devoir gérer une erreur spécifique “code de retour”. Cela peut parfois aider à voir l’impact d’une idée pour un changement de code de bas niveau aussi … déclarez une exception vérifiée en aval et voyez qui devrait ajuster. Ce dernier point ne s’applique pas s’il y a beaucoup d’ exceptions : catch (Exception e) ou Throws Exception qui n’est généralement pas trop bien pensé.

Voici ce que je veux partager mon opinion après de nombreuses années d’expérience en développement:

  1. Exception vérifiée. Cela fait partie du cas d’utilisation de l’entreprise ou du stream d’appels, cela fait partie de la logique de l’application à laquelle on s’attend ou non. Par exemple, la connexion refusée, la condition n’est pas satisfaite, etc. Je l’appelle généralement une exception de post-traitement ou une exception “utilisateur”.

  2. Exception non vérifiée Ceci est une partie de l’exception de programmation, une erreur dans la programmation du code logiciel (bug, défaut) et reflète la façon dont les programmeurs doivent utiliser l’API selon la documentation. Si un document externe lib / framework indique qu’il s’attend à obtenir des données dans une certaine plage et que leur valeur est nulle, parce que les exceptions NPE ou IllegalArgumentException seront lancées, le programmeur doit s’y attendre et utiliser l’API correctement, conformément à la documentation. Sinon, l’exception sera levée. Je l’appelle habituellement une exception de prétraitement ou une exception de “validation”.

Par public cible Parlons maintenant du public cible ou du groupe de personnes pour lequel les exceptions ont été conçues (selon mon opinion):

  1. Exception vérifiée. Le public cible est les utilisateurs / clients.
  2. Exception non vérifiée Le public cible est les développeurs. En d’autres termes, les exceptions non vérifiées sont conçues uniquement pour les développeurs.

Par phase de cycle de développement de l’application.

  1. L’exception vérifiée est conçue pour exister tout au long du cycle de vie de la production, et le mécanisme attendu d’une application gère des cas exceptionnels.
  2. Les exceptions non contrôlées sont conçues pour exister uniquement pendant le cycle de vie de développement / test de l’application. Elles doivent toutes être corrigées pendant cette période et ne doivent pas être lancées lorsqu’une application s’exécute déjà en production.

La raison pour laquelle les frameworks utilisent généralement des exceptions non vérifiées (Spring, par exemple) est que le framework ne peut pas déterminer la logique métier de votre application, c’est aux développeurs de les détecter et de concevoir leur propre logique.

Les exceptions vérifiées sont utiles pour les cas récupérables pour lesquels vous souhaitez fournir des informations à l’appelant (permissions insuffisantes, fichier introuvable, etc.).

Les exceptions non vérifiées sont rarement utilisées, voire pas du tout, pour informer l’utilisateur ou le programmeur des erreurs graves ou des conditions inattendues pendant l’exécution. Ne les lancez pas si vous écrivez du code ou des bibliothèques qui seront utilisées par d’autres, car ils ne s’attendent peut-être pas à ce que votre logiciel lance des exceptions non vérifiées car le compilateur ne les force pas à être attrapé ou déclaré.

Si une exception est moins probable, et nous pouvons continuer même après avoir attrapé cela, et nous ne pouvons rien faire pour éviter cette exception, nous pouvons utiliser une exception vérifiée.

Chaque fois que nous voulons faire quelque chose de significatif quand une exception particulière se produit et quand cette exception est attendue mais pas certaine, alors nous pouvons utiliser l’exception vérifiée.

Chaque fois qu’une exception navigue dans différentes couches, nous n’avons pas besoin de l’attraper dans chaque couche, dans ce cas, nous pouvons utiliser une exception d’exécution ou une exception wrap en tant qu’exception non contrôlée.

L’exception d’exécution est utilisée lorsqu’une exception est susceptible de se produire, il n’y a aucun moyen d’aller plus loin et rien ne peut être récupéré. Donc, dans ce cas, nous pouvons prendre des précautions concernant cette exception. EX: NUllPointerException, ArrayOutofBoundsException. Celles-ci sont plus susceptibles de se produire. Dans ce scénario, nous pouvons prendre des précautions lors du codage pour éviter une telle exception. Sinon, nous devrons écrire des blocs de capture à chaque fois.

Des exceptions plus générales peuvent être faites. Les cases non cochées, moins générales, sont vérifiées.

Je pense que nous pouvons penser à des exeptions de plusieurs questions:

pourquoi l’exeption se produit-elle? Que pouvons-nous faire quand cela arrive

par erreur, un bug. comme une méthode d’object nul est appelée.

 Ssortingng name = null; ... // some logics System.out.print(name.length()); // name is still null here 

Ce type d’exception devrait être corrigé pendant le test. Sinon, il casse la production et vous obtenez un bogue très élevé qui doit être corrigé immédiatement. Ce type d’exceptions n’a pas besoin d’être vérifié.

par entrée externe, vous ne pouvez pas contrôler ou faire confiance à la sortie du service externe.

 Ssortingng name = ExternalService.getName(); // return null System.out.print(name.length()); // name is null here 

Ici, vous devrez peut-être vérifier si le nom est null si vous souhaitez continuer quand il est nul, sinon vous pouvez le laisser seul et il s’arrêtera ici et donnera à l’appelant l’exception d’exécution. Ce type d’exceptions n’a pas besoin d’être vérifié.

par exception d’exécution externe, vous ne pouvez pas contrôler ou faire confiance au service externe.

Ici, vous devrez peut-être intercepter toutes les exceptions de ExternalService si vous souhaitez continuer lorsque cela se produit, sinon vous pouvez le laisser tranquille et cela s’arrêtera ici et donnera à l’appelant l’exception d’exécution.

en cochant exception de external, vous ne pouvez pas contrôler ou faire confiance au service externe.

Ici, vous devrez peut-être intercepter toutes les exceptions de ExternalService si vous souhaitez continuer lorsque cela se produit, sinon vous pouvez le laisser tranquille et cela s’arrêtera ici et donnera à l’appelant l’exception d’exécution.

Dans ce cas, avons-nous besoin de savoir quel type d’exception s’est produite dans ExternalService? Ça dépend:

  1. Si vous pouvez gérer certains types d’exceptions, vous devez les détecter et les traiter. Pour les autres, faites-les bouillonner.

  2. Si vous avez besoin d’un journal ou d’une réponse à l’utilisateur spécifique, vous pouvez les récupérer. Pour les autres, faites-les bouillonner.

Je pense que lorsque vous déclarez une exception d’application, il doit s’agir d’une exception non contrôlée, c’est-à-dire une sous-classe de RuntimeException. La raison en est qu’elle n’encombrera pas le code de l’application avec try-catch et lancera la déclaration sur la méthode. Si votre application utilise Java Api qui lève les exceptions vérifiées, il doit quand même être manipulé. Pour les autres cas, l’application peut lancer une exception non contrôlée. Si l’appelant de l’application doit toujours gérer des exceptions non vérifiées, cela peut être fait.

Nous devons distinguer ces deux types d’exception selon qu’il s’agit d’une erreur de programmeur ou non.

  • Si une erreur est une erreur du programmeur, il doit s’agir d’une exception non vérifiée . Par exemple: SQLException / IOException / NullPointerException. Ces exceptions sont des erreurs de programmation. Ils doivent être gérés par le programmeur. Alors que dans l’API JDBC, SQLException est une exception vérifiée, dans Spring JDBCTemplate c’est une exception non contrôlée. Le programmeur ne s’inquiète pas de SqlException, lorsqu’il est utilisé Spring.
  • Si une erreur n’est pas une erreur du programmeur et que la raison vient de l’extérieur, il doit s’agir d’une exception vérifiée. Par exemple: si le fichier est supprimé ou si l’autorisation de fichier est modifiée par quelqu’un d’autre, il doit être récupéré.

FileNotFoundException est un bon exemple pour comprendre les différences subtiles. FileNotFoundException est levée dans le cas où le fichier n’est pas trouvé. Il y a deux raisons à cette exception. Si le chemin d’access au fichier est défini par le développeur ou pris par l’utilisateur final via l’interface graphique, il doit s’agir d’une exception non vérifiée. Si le fichier est supprimé par quelqu’un d’autre, il devrait s’agir d’une exception vérifiée.

Les exceptions vérifiées peuvent être traitées de deux manières. Ceux-ci utilisent try-catch ou propagent l’exception. En cas de propagation d’une exception, toutes les méthodes de la stack d’appels seront étroitement liées en raison de la gestion des exceptions. C’est pourquoi, nous devons utiliser soigneusement les exceptions vérifiées.

Si vous développez un système d’entreprise en couches, vous devez choisir la plupart des exceptions non contrôlées à lancer, mais n’oubliez pas d’utiliser l’exception vérifiée pour le cas où vous ne pouvez rien faire.

La règle que j’utilise est: n’utilisez jamais d’exceptions non vérifiées! (ou quand vous ne voyez aucun moyen de le contourner)

Du sharepoint vue du développeur utilisant votre bibliothèque ou de l’utilisateur final utilisant votre bibliothèque / application, il est vraiment désagréable d’être confronté à une application qui tombe en panne à cause d’une exception non traitée. Et compter sur un fourre-tout n’est pas bon non plus.

De cette façon, l’utilisateur final peut toujours recevoir un message d’erreur au lieu que l’application disparaisse complètement.