Bonnes pratiques pour la gestion des exceptions en Java ou C # [fermé]

117

Je ne peux pas décider comment gérer les exceptions dans mon application.

Beaucoup si mes problèmes avec des exceptions viennent 1) de l'accès aux données via un service distant ou 2) de la désérialisation d'un objet JSON. Malheureusement, je ne peux garantir le succès de l'une ou l'autre de ces tâches (coupure de la connexion réseau, objet JSON mal formé qui est hors de mon contrôle).

En conséquence, si je rencontre une exception, je l'attrape simplement dans la fonction et renvoie FALSE à l'appelant. Ma logique est que tout ce qui importe vraiment à l'appelant est de savoir si la tâche a réussi, pas pourquoi elle n'a pas réussi.

Voici un exemple de code (en JAVA) d'une méthode typique)

public boolean doSomething(Object p_somthingToDoOn)
{
    boolean result = false;

    try{
        // if dirty object then clean
        doactualStuffOnObject(p_jsonObject);

        //assume success (no exception thrown)
        result = true;
    }
    catch(Exception Ex)
    {
        //don't care about exceptions
        Ex.printStackTrace();
    }
    return result;
}

Je pense que cette approche est bonne, mais je suis vraiment curieux de savoir quelles sont les meilleures pratiques pour gérer les exceptions (devrais-je vraiment faire apparaître une exception tout au long d'une pile d'appels?).

En résumé des questions clés:

  1. Est-il acceptable de simplement attraper des exceptions mais de ne pas les faire apparaître ou de notifier formellement le système (via un journal ou une notification à l'utilisateur)?
  2. Quelles sont les meilleures pratiques pour les exceptions qui n'entraînent pas que tout nécessite un bloc try / catch?

Suivi / Modifier

Merci pour tous vos commentaires, nous avons trouvé d'excellentes sources sur la gestion des exceptions en ligne:

Il semble que la gestion des exceptions est l'une de ces choses qui varient en fonction du contexte. Mais surtout, il faut être cohérent dans la façon dont ils gèrent les exceptions au sein d'un système.

De plus, faites attention à la pourriture du code via des essais / captures excessifs ou en ne respectant pas une exception (une exception avertit le système, que faut-il encore avertir?).

En outre, c'est un joli commentaire de choix de m3rLinEz .

J'ai tendance à être d'accord avec Anders Hejlsberg et vous que la plupart des appelants ne se soucient que de savoir si l'opération réussit ou non.

À partir de ce commentaire, il soulève quelques questions à prendre en compte lors du traitement des exceptions:

  • À quel point cette exception est-elle lancée?
  • Comment est-il logique de le gérer?
  • L'appelant se soucie-t-il vraiment de l'exception ou se soucie-t-il simplement de la réussite de l'appel?
  • Le fait de forcer un appelant à gérer une exception potentielle est-il gracieux?
  • Êtes-vous respectueux des idomes de la langue?
    • Avez-vous vraiment besoin de renvoyer un indicateur de succès comme booléen? Renvoyer un booléen (ou un int) est plus un état d'esprit C qu'un Java (en Java, vous ne feriez que gérer l'exception).
    • Suivez les constructions de gestion des erreurs associées à la langue :)!
AtariPete
la source
Bien que l'article de la communauté oracle soit en java, il s'agit d'un conseil générique pour une classe assez large de langues. Bel article, exactement ce que je cherchais.
Bunny Rabbit

Réponses:

61

Il me semble étrange que vous vouliez attraper des exceptions et les transformer en codes d'erreur. Pourquoi pensez-vous que l'appelant préférerait les codes d'erreur aux exceptions lorsque cette dernière est la valeur par défaut à la fois en Java et en C #?

Quant à vos questions:

  1. Vous ne devez attraper que les exceptions que vous pouvez réellement gérer. Attraper des exceptions n'est pas la bonne chose à faire dans la plupart des cas. Il y a quelques exceptions (par exemple la journalisation et le rassemblement d'exceptions entre les threads) mais même dans ces cas, vous devriez généralement renvoyer les exceptions.
  2. Vous ne devriez certainement pas avoir beaucoup d'instructions try / catch dans votre code. Encore une fois, l'idée est de n'attraper que les exceptions que vous pouvez gérer. Vous pouvez inclure un gestionnaire d'exceptions le plus élevé pour transformer les exceptions non gérées en quelque chose d'utile pour l'utilisateur final, mais sinon, vous ne devriez pas essayer d'attraper chaque exception à chaque endroit possible.
Brian Rasmussen
la source
Quant à savoir pourquoi quelqu'un voudrait des codes d'erreur au lieu d'exceptions ... J'ai toujours pensé que c'était bizarre que HTTP utilise toujours des codes d'erreur, même si mon application génère une exception. Pourquoi HTTP ne peut-il pas me laisser passer l'exception telle quelle?
Trejkaz
le mieux que vous puissiez faire est d'envelopper vos codes d'erreur dans une monade
lindenrovio
@Trejkaz Vous ne souhaitez pas renvoyer le détail de l'exception aux utilisateurs, car c'est un risque de sécurité. C'est pourquoi les serveurs HTML renvoient des codes d'erreur. C'est aussi un problème de localisation pour renvoyer un message d'erreur, et rend probablement le HTML plus gros et plus lent à retourner. Tout cela explique pourquoi je pense que les serveurs HTML renvoient des codes d'erreur.
Didier A.
Je pense qu'il vaut mieux dire: "Vous ne devriez supprimer que les exceptions que vous pouvez réellement gérer."
Didier A.
@didibus Pourquoi pensez-vous que les problèmes de sécurité devraient créer un inconvénient lors du développement? Je n'ai jamais rien dit sur la production. En ce qui concerne la localisation des messages d'erreur, l'ensemble du site Web a déjà ce problème et les gens semblent y faire face.
Trejkaz
25

Cela dépend de l'application et de la situation. Si vous créez un composant de bibliothèque, vous devez faire apparaître des exceptions, même si elles doivent être encapsulées pour être contextuelles avec votre composant. Par exemple, si vous créez une base de données Xml et disons que vous utilisez le système de fichiers pour stocker vos données, et que vous utilisez les autorisations du système de fichiers pour sécuriser les données. Vous ne voudriez pas faire apparaître une exception FileIOAccessDenied car cela fuit votre implémentation. Au lieu de cela, vous encapsuleriez l'exception et lèveriez une erreur AccessDenied. Cela est particulièrement vrai si vous distribuez le composant à des tiers.

Quant à savoir s'il est normal d'avaler des exceptions. Cela dépend de votre système. Si votre application peut gérer les cas d'échec et qu'il n'y a aucun avantage à informer l'utilisateur pourquoi elle a échoué, continuez, bien que je vous recommande fortement de consigner l'échec. J'ai toujours trouvé frustrant d'être appelé pour aider à résoudre un problème et constater qu'ils avalaient l'exception (ou la remplaçaient et en lançaient une nouvelle à la place sans définir l'exception interne).

En général, j'utilise les règles suivantes:

  1. Dans mes composants et bibliothèques, je n'attrape une exception que si j'ai l'intention de la gérer ou de faire quelque chose en fonction de celle-ci. Ou si je souhaite fournir des informations contextuelles supplémentaires dans une exception.
  2. J'utilise une prise d'essai générale au point d'entrée de l'application, ou au plus haut niveau possible. Si une exception arrive ici, je la consigne simplement et la laisse échouer. Idéalement, les exceptions ne devraient jamais arriver ici.

Je trouve que le code suivant est une odeur:

try
{
    //do something
}
catch(Exception)
{
   throw;
}

Un code comme celui-ci ne sert à rien et ne doit pas être inclus.

JoshBerke
la source
@Josh, bon point à propos de la déglutition des exceptions mais je crois qu'il y a peu de cas où il est acceptable de simplement avaler des exceptions. Dans le dernier projet, votre extrait de code était obligatoire, ça puait. Les enregistrer tous a rendu les choses pires, mon conseil, si vous ne pouvez pas gérer l'exception, essayez de ne pas l'avaler.
smaclell le
Comme je l'ai dit, tout dépend de l'application et du contexte spécifique. Il y a des moments où j'avale des exceptions bien que ce soit rare, et je ne me souviens pas de la dernière fois que je l'ai fait ;-) C'était probablement quand j'écrivais mon propre enregistreur, et l'écriture dans le journal, et le journal secondaire a échoué.
JoshBerke
Le code sert un point: vous pouvez définir un point d'arrêt au niveau du «lancer».
Rauhotz
3
Point faible, vous pouvez dire à VS de rompre à toute exception levée ou vous pouvez la réduire et choisir une exception spécifique. Dans VS2008, il y a un élément de menu en cours de débogage (vous devrez personnaliser vos barres d'outils pour le trouver) Exceptions
appelées
L'exemple «odeur de code» a un effet secondaire certain, même sous cette forme simple. Si // do somethinginclut des try/finallyblocs autour du point qui jette, les finallyblocs s'exécuteront avant le catchbloc. Sans le try/catch, l'exception volera jusqu'au sommet de la pile sans qu'aucun finallybloc ne soit exécuté. Cela permet au gestionnaire de niveau supérieur de décider d'exécuter ou non les finallyblocs.
Daniel Earwicker le
9

Je voudrais recommander une autre bonne source sur le sujet. C'est une interview avec les inventeurs de C # et Java, Anders Hejlsberg et James Gosling respectivement, sur le thème de l'exception vérifiée de Java.

Échec et exceptions

Il y a aussi d'excellentes ressources au bas de la page.

J'ai tendance à être d'accord avec Anders Hejlsberg et vous que la plupart des appelants ne se soucient que de savoir si l'opération réussit ou non.

Bill Venners : Vous avez évoqué des problèmes d'évolutivité et de version concernant les exceptions vérifiées. Pourriez-vous clarifier ce que vous entendez par ces deux questions?

Anders Hejlsberg : Commençons par la gestion des versions, car les problèmes sont assez faciles à voir. Disons que je crée une méthode foo qui déclare qu'elle lève les exceptions A, B et C.Dans la version deux de foo, je veux ajouter un tas de fonctionnalités, et maintenant foo pourrait lancer l'exception D.C'est un changement radical pour moi de ajoutez D à la clause throws de cette méthode, car l'appelant existant de cette méthode ne gérera presque certainement pas cette exception.

L'ajout d'une nouvelle exception à une clause throws dans une nouvelle version casse le code client. C'est comme ajouter une méthode à une interface. Une fois que vous avez publié une interface, elle est à toutes fins pratiques immuable, car toute implémentation de celle-ci peut avoir les méthodes que vous souhaitez ajouter dans la prochaine version. Vous devez donc créer une nouvelle interface à la place. De même, avec des exceptions, vous devrez soit créer une toute nouvelle méthode appelée foo2 qui lève plus d'exceptions, soit intercepter l'exception D dans le nouveau foo et transformer le D en A, B ou C.

Bill Venners : Mais ne cassez -vous pas leur code dans ce cas de toute façon, même dans une langue sans exceptions vérifiées? Si la nouvelle version de foo va lancer une nouvelle exception que les clients devraient penser à gérer, leur code n'est-il pas cassé simplement par le fait qu'ils ne s'attendaient pas à cette exception lorsqu'ils ont écrit le code?

Anders Hejlsberg : Non, car dans bien des cas, les gens s'en moquent. Ils ne traiteront aucune de ces exceptions. Il existe un gestionnaire d'exceptions de niveau inférieur autour de leur boucle de message. Ce gestionnaire va simplement ouvrir une boîte de dialogue indiquant ce qui n'a pas fonctionné et continuer. Les programmeurs protègent leur code en écrivant «try finally», donc ils reculeront correctement si une exception se produit, mais ils ne sont pas réellement intéressés par la gestion des exceptions.

La clause throws, du moins la façon dont elle est implémentée en Java, ne vous oblige pas nécessairement à gérer les exceptions, mais si vous ne les gérez pas, elle vous oblige à reconnaître précisément les exceptions qui peuvent passer. Cela vous oblige à intercepter les exceptions déclarées ou à les mettre dans votre propre clause throws. Pour contourner cette exigence, les gens font des choses ridicules. Par exemple, ils décorent chaque méthode avec «throws Exception». Cela annule complètement la fonctionnalité, et vous venez de demander au programmeur d'écrire plus de gunk gobbledy. Cela n'aide personne.

EDIT: Ajout de plus de détails sur la converstaion

Gant
la source
Merci pour cela! J'ai mis à jour ma question avec des informations sur votre réponse!
AtariPete
Il semble que M. Hejlsberg justifie la gestion des exceptions Pokemon. L'un des gros problèmes avec la conception d'exceptions en Java et C # est que trop d'informations sont codées dans le type d'une exception, alors que les informations devraient être stockées dans des instances d'exception ne sont pas disponibles de manière cohérente. Les exceptions devraient se propager dans la pile d'appels jusqu'à ce que toutes les conditions anormales ainsi représentées aient été résolues; malheureusement, le type d'exception - même s'il est reconnu - n'indique guère si une situation est résolue. Si une exception n'est pas reconnue ...
supercat
... la situation est encore pire. Si le code appelle FetchDataet qu'il lève une exception d'un type inattendu, il n'a aucun moyen de savoir si cette exception signifie simplement que les données sont indisponibles (auquel cas la capacité du code à s'en sortir sans elle la «résoudrait»), ou si cela signifie que le CPU est en feu et que le système doit effectuer un «arrêt de sécurité» à la première occasion. On dirait que M. Hejlsberg suggère que le code devrait assumer le premier; c'est peut-être la meilleure stratégie possible étant donné les hiérarchies d'exceptions existantes, mais cela semble néanmoins dégoûtant.
supercat
Je suis d'accord pour dire que lancer Exceptin est ridicule, car presque tout peut lancer une exception, vous devriez simplement supposer que cela peut arriver. Mais lorsque vous spécifiez des exceptions comme les lancers A, B, C, ce n'est qu'une annotation, pour moi, cela devrait être utilisé comme un bloc de commentaire. C'est comme dire, bon client de ma fonction, voici une astuce, peut-être que vous voulez vous occuper de A, B, C, car ces erreurs sont susceptibles de se produire lors de l'utilisation de moi. Si vous ajoutez D à l'avenir, ce n'est pas un gros problème si ce n'est pas traité, mais c'est comme ajouter une nouvelle documentation, Oh au fait, maintenant il serait également utile d'attraper D.
Didier A.
8

Les exceptions cochées sont un problème controversé en général, et en Java en particulier (plus tard, je vais essayer de trouver quelques exemples pour ceux qui sont pour et qui s'y opposent).

En règle générale, la gestion des exceptions doit être quelque chose autour de ces directives, sans ordre particulier:

  • Par souci de maintenabilité, consignez toujours les exceptions afin que lorsque vous commencez à voir des bogues, le journal vous aidera à vous indiquer l'endroit où votre bogue a probablement commencé. Ne partez jamais printStackTrace()ou quelque chose de semblable, il y a de fortes chances que l'un de vos utilisateurs finisse par obtenir l'une de ces traces de pile et qu'il ne sache absolument pas quoi en faire.
  • Attrapez les exceptions que vous pouvez gérer, et seulement celles-ci, et gérez-les , ne les jetez pas simplement dans la pile.
  • Attrapez toujours une classe d'exception spécifique, et généralement vous ne devriez jamais attraper de type Exception, vous êtes très susceptible d'avaler des exceptions autrement importantes.
  • Jamais (jamais) attraper Errors !! , ce qui signifie: Ne jamais attraper Throwables car les Errors sont des sous-classes de ces derniers. Errors sont des problèmes que vous ne pourrez probablement jamais gérer (par exemple OutOfMemory, ou d'autres problèmes de JVM)

Concernant votre cas spécifique, assurez-vous que tout client appelant votre méthode recevra la valeur de retour appropriée. Si quelque chose échoue, une méthode de retour booléen peut retourner false, mais assurez-vous que les endroits que vous appelez cette méthode sont capables de gérer cela.

Yuval Adam
la source
Les exceptions vérifiées ne sont pas un problème en C # car elles ne les ont pas.
cletus
3
Imho, parfois il est bon d'attraper les erreurs: je me souviens d'une application Java très gourmande en mémoire que j'ai écrite. J'ai attrapé le OutOfMemory-Ex, et ai montré un message à l'utilisateur qu'il n'avait plus de mémoire, qu'il devrait quitter d'autres programmes et lui ai dit comment démarrer le jvm avec plus d'espace de tas assigné. Je suppose que cela a aidé.
Lena Schimmel le
5

Vous ne devriez attraper que les exceptions que vous pouvez gérer. Par exemple, si vous avez affaire à la lecture sur un réseau et que la connexion expire et que vous obtenez une exception, vous pouvez réessayer. Cependant, si vous lisez sur un réseau et obtenez une exception IndexOutOfBounds, vous ne pouvez vraiment pas gérer cela car vous ne savez pas (enfin, dans ce cas, vous ne saurez pas) ce qui l'a causé. Si vous allez renvoyer false ou -1 ou null, assurez-vous que c'est pour des exceptions spécifiques. Je ne veux pas qu'une bibliothèque que j'utilise renvoie un faux sur une lecture réseau lorsque l'exception levée est que le tas est à court de mémoire.

Malfist
la source
3

Les exceptions sont des erreurs qui ne font pas partie de l'exécution normale du programme. En fonction de ce que fait votre programme et de ses utilisations (c'est-à-dire un traitement de texte par rapport à un moniteur cardiaque), vous voudrez faire des choses différentes lorsque vous rencontrez une exception. J'ai travaillé avec du code qui utilise des exceptions dans le cadre de l'exécution normale et c'est définitivement une odeur de code.

Ex.

try
{
   sendMessage();

   if(message == success)
   {
       doStuff();
   }
   else if(message == failed)
   {
       throw;
   }
}
catch(Exception)
{
    logAndRecover();
}

Ce code me rend barf. OMI, vous ne devriez pas récupérer des exceptions à moins que ce soit un programme critique. Si vous lancez des exceptions, de mauvaises choses se produisent.

Holograham
la source
2

Tout ce qui précède semble raisonnable et votre lieu de travail peut souvent avoir une politique. Chez nous, nous avons défini les types d'exception: SystemException(non cochée) et ApplicationException(cochée).

Nous avons convenu qu'il SystemExceptionest peu probable que les s soient récupérables et qu'ils seront traités une fois au sommet. Fournir davantage de contexte, nos SystemExceptions sont exteneded pour indiquer où ils se sont produits, par exemple RepositoryException, ServiceEceptionetc.

ApplicationExceptionLes s peuvent avoir une signification commerciale comme InsufficientFundsExceptionet doivent être gérées par le code client.

Sans un exemple concret, il est difficile de commenter votre implémentation, mais je n'utiliserais jamais de codes de retour, c'est un problème de maintenance. Vous pouvez avaler une exception, mais vous devez décider pourquoi et toujours consigner l'événement et le stacktrace. Enfin, comme votre méthode n'a pas d'autre traitement, elle est assez redondante (sauf pour l'encapsulation?), Donc doactualStuffOnObject(p_jsonObject);pourrait retourner un booléen!


la source
1

Après avoir réfléchi et examiné votre code, il me semble que vous relancez simplement l'exception en tant que booléen. Vous pouvez simplement laisser la méthode passer cette exception (vous n'avez même pas besoin de l'attraper) et la gérer dans l'appelant, car c'est là que cela compte. Si l'exception oblige l'appelant à réessayer cette fonction, l'appelant doit être celui qui intercepte l'exception.

Il peut parfois arriver que l'exception que vous rencontrez n'ait pas de sens pour l'appelant (c'est-à-dire qu'il s'agit d'une exception réseau), auquel cas vous devez l'envelopper dans une exception spécifique au domaine.

Si d'un autre côté, l'exception signale une erreur irrécupérable dans votre programme (c'est-à-dire que le résultat éventuel de cette exception sera la fin du programme), j'aime personnellement rendre cela explicite en l'attrapant et en lançant une exception d'exécution.

wds
la source
1

Si vous comptez utiliser le modèle de code dans votre exemple, appelez-le TryDoSomething et interceptez uniquement des exceptions spécifiques.

Pensez également à utiliser un filtre d'exception lors de la journalisation des exceptions à des fins de diagnostic. VB prend en charge la langue pour les filtres d'exception. Le lien vers le blog de Greggm a une implémentation qui peut être utilisée à partir de C #. Les filtres d'exception ont de meilleures propriétés de débogage par rapport à la capture et à la relance. Plus précisément, vous pouvez enregistrer le problème dans le filtre et laisser l'exception continuer à se propager. Cette méthode permet à un débogueur JIT (Just in Time) de joindre la pile d'origine complète. Une relance coupe la pile au moment où elle a été relancée.

Les cas où TryXXXX a du sens sont lorsque vous encapsulez une fonction tierce qui lance des cas qui ne sont pas vraiment exceptionnels ou qui sont simples et difficiles à tester sans appeler la fonction. Un exemple serait quelque chose comme:

// throws NumberNotHexidecimalException
int ParseHexidecimal(string numberToParse); 

bool TryParseHexidecimal(string numberToParse, out int parsedInt)
{
     try
     {
         parsedInt = ParseHexidecimal(numberToParse);
         return true;
     }
     catch(NumberNotHexidecimalException ex)
     {
         parsedInt = 0;
         return false;
     }
     catch(Exception ex)
     {
         // Implement the error policy for unexpected exceptions:
         // log a callstack, assert if a debugger is attached etc.
         LogRetailAssert(ex);
         // rethrow the exception
         // The downside is that a JIT debugger will have the next
         // line as the place that threw the exception, rather than
         // the original location further down the stack.
         throw;
         // A better practice is to use an exception filter here.
         // see the link to Exception Filter Inject above
         // http://code.msdn.microsoft.com/ExceptionFilterInjct
     }
}

Que vous utilisiez ou non un modèle comme TryXXX est plus une question de style. La question de saisir toutes les exceptions et de les avaler n'est pas une question de style. Assurez-vous que les exceptions inattendues sont autorisées à se propager!

Steve Steiner
la source
J'adore le modèle TryXXX en .net.
JoshBerke
1

Je suggère de vous inspirer de la bibliothèque standard pour la langue que vous utilisez. Je ne peux pas parler pour C #, mais regardons Java.

Par exemple, java.lang.reflect.Array a une setméthode statique :

static void set(Object array, int index, Object value);

La voie C serait

static int set(Object array, int index, Object value);

... avec la valeur de retour étant un indicateur de succès. Mais vous n'êtes plus dans le monde C.

Une fois que vous avez adopté les exceptions, vous devriez constater que cela rend votre code plus simple et plus clair, en éloignant votre code de gestion des erreurs de votre logique de base. Essayez d'avoir beaucoup d'instructions dans un seul trybloc.

Comme d'autres l'ont noté, vous devez être aussi précis que possible dans le type d'exception que vous détectez.

svelte
la source
c'est un commentaire très valable, soyez respectueux de la langue et de la façon dont elle gère traditionnellement ces problèmes. N'introduisez pas un état d'esprit C dans un monde Java.
AtariPete
0

Si vous allez intercepter une exception et renvoyer false, cela devrait être une exception très spécifique. Vous ne faites pas cela, vous les attrapez tous et vous retournez faux. Si j'obtiens une MyCarIsOnFireException, je veux en savoir plus tout de suite! Le reste des exceptions dont je ne me soucie peut-être pas. Vous devriez donc avoir une pile de gestionnaires d'exceptions qui disent "whoa whoa quelque chose ne va pas ici" pour certaines exceptions (relancez, ou attrapez et relancez une nouvelle exception qui explique mieux ce qui s'est passé) et renvoyez simplement false pour d'autres.

S'il s'agit d'un produit que vous allez lancer, vous devriez enregistrer ces exceptions quelque part, cela vous aidera à peaufiner les choses à l'avenir.

Edit: Quant à la question de tout emballer dans un try / catch, je pense que la réponse est oui. Les exceptions doivent être si rares dans votre code que le code du bloc catch s'exécute si rarement qu'il n'atteint pas du tout les performances. Une exception devrait être un état dans lequel votre machine d'état est tombée en panne et ne sait pas quoi faire. Au moins, renvoyez une exception qui explique ce qui se passait à ce moment-là et contient l'exception interceptée. «Exception dans la méthode doSomeStuff ()» n'est pas très utile pour quiconque doit comprendre pourquoi il s'est cassé pendant que vous êtes en vacances (ou à un nouvel emploi).

jcollum
la source
N'oubliez pas que la configuration d'un bloc d'exceptions coûte aussi ...
devstuff
0

Ma stratégie:

Si la fonction d'origine a renvoyé void, je la change pour retourner bool . Si une exception / erreur s'est produite, retournez false , si tout va bien, retournez true .

Si la fonction doit retourner quelque chose, quand une exception / erreur s'est produite, renvoie null , sinon l'élément retournable.

Au lieu de booléen, une chaîne peut être renvoyée contenant la description de l'erreur.

Dans tous les cas, avant de retourner quoi que ce soit, enregistrez l'erreur.

Tempête de germes
la source
0

Quelques excellentes réponses ici. Je voudrais ajouter que si vous vous retrouvez avec quelque chose comme vous l'avez posté, imprimez au moins plus que la trace de pile. Dites ce que vous faisiez à l'époque, et Ex.getMessage (), pour donner au développeur une chance de se battre.

dj_segfault
la source
je suis entièrement d'accord. Je n'ai fait qu'Ex.printStackTrace (); comme exemple de quelque chose que je faisais dans la capture (c'est-à-dire ne pas relancer).
AtariPete
0

Les blocs try / catch forment un deuxième ensemble de logique intégré au premier ensemble (principal), en tant que tels, ils sont un excellent moyen de marteler du code spaghetti illisible et difficile à déboguer.

Pourtant, utilisés raisonnablement, ils fonctionnent à merveille en termes de lisibilité, mais vous devez simplement suivre deux règles simples:

  • utilisez-les (avec parcimonie) au bas niveau pour attraper les problèmes de gestion de la bibliothèque et les renvoyer dans le flux logique principal. La plupart de la gestion des erreurs que nous souhaitons doit provenir du code lui-même, dans le cadre des données elles-mêmes. Pourquoi faire des conditions spéciales, si les données renvoyées ne sont pas spéciales?

  • utilisez un gros gestionnaire au niveau supérieur pour gérer tout ou partie des conditions étranges qui se produisent dans le code et qui ne sont pas capturées à un niveau bas. Faites quelque chose d'utile avec les erreurs (journaux, redémarrages, récupérations, etc.).

En dehors de ces deux types de gestion des erreurs, tout le reste du code au milieu doit être libre et exempt de code try / catch et d'objets d'erreur. De cette façon, il fonctionne simplement et comme prévu, peu importe où vous l'utilisez ou ce que vous en faites.

Paul.

Paul W Homer
la source
0

Je suis peut-être un peu en retard avec la réponse, mais la gestion des erreurs est quelque chose que nous pouvons toujours changer et évoluer avec le temps. Si vous voulez en savoir plus sur ce sujet, j'ai écrit un article à ce sujet dans mon nouveau blog. http://taoofdevelopment.wordpress.com

Bon codage.

GRGodoi
la source