Comment implémenter la gestion des erreurs [fermé]

13

Même si j'ai programmé à un niveau professionnel depuis quelques années, je ne comprends toujours pas complètement la gestion des erreurs. Bien que mes applications fonctionnent correctement, la gestion des erreurs n'est pas implémentée à un niveau professionnel et est un mélange de plusieurs techniques.

Il n'y a aucune structure derrière ma gestion des erreurs. J'aimerais apprendre et comprendre comment il est mis en œuvre au niveau professionnel. C'est un domaine où je manque de connaissances.

Quand dois-je utiliser une exception et quand dois-je retourner un état de réussite, à vérifier dans le flux logique? Est-il correct de mélanger l'exception et de renvoyer un statut?

Je code principalement en C #.

James Jeffery
la source
2
Pourquoi voter contre? Je pose une question sérieuse sur la mise en œuvre de la gestion des erreurs et comment elle est effectuée. Si ce n'est pas le meilleur endroit pour poser une telle question parmi les programmeurs, alors où est-il? Cela me dérange vraiment quand les gens votent de telles questions parce qu'il n'y a nulle part ailleurs où poser une telle question. C'est probablement le seul endroit sur le Web où je vais obtenir une réponse fiable et des ressources possibles. Donc, au lieu de voter contre une question que d'autres personnes vont sûrement Google, ne serait-il pas plus facile d'y répondre?
James Jeffery
6
Votre question est très large. Peut-être pourriez-vous restreindre la portée en rapportant des exemples spécifiques de la façon dont vous n'avez pas atteint vos objectifs de codage.
Andyz Smith
Il existe de nombreux articles sur le Web concernant la gestion des erreurs: Essayez ceci: msdn.microsoft.com/en-us/library/seyhszts.aspx
Nir Kornfeld

Réponses:

25
  1. Utilisez des exceptions pour des choses exceptionnelles, des choses que vous ne pouvez raisonnablement pas vous attendre à rencontrer trop souvent, des choses qui indiquent que quelque chose ne va pas. Par exemple, si le réseau est en panne, c'est une chose exceptionnelle pour un serveur web. Si la base de données n'est pas disponible, cela signifie que quelque chose ne va pas. Si le fichier de configuration est manquant, cela signifie probablement que l'utilisateur s'est trompé avec lui.

  2. N'utilisez pas d'exceptions pour gérer un code incorrect. Afin de vérifier l'exactitude du code, vous devez utiliser soit les assertions, soit, dans .NET Framework 4 et versions ultérieures, les contrats de code (qui remplacent les assertions et présentent des fonctionnalités supplémentaires particulièrement utiles).

  3. N'utilisez pas d'exceptions dans des cas non exceptionnels. Le fait que l'utilisateur, lorsqu'on lui a demandé d'entrer un numéro, a saisi "chien" n'est pas si exceptionnel qu'il mérite une exception.

  4. Soyez prudent lorsque vous choisissez les types d'exceptions. Créez vos propres types si nécessaire. Choisissez soigneusement l'héritage, en gardant à l'esprit que les parents attrapeurs attraperont également les enfants. Jamais throw Exception.

  5. N'utilisez pas de codes retour pour les erreurs. Les codes d'erreur sont facilement masqués, ignorés, oubliés. S'il y a une erreur, gérez-la ou propagez-la dans la pile supérieure.

  6. Dans les cas où une méthode devrait renvoyer une erreur et que l'erreur n'est pas exceptionnelle, utilisez des énumérations, jamais des numéros d'erreur. Exemple:

    // Note that the operation fails pretty often, since it deals with the servers which are
    // frequently unavailable, and the ones which send garbage instead of the actual data.
    private LoadOperationResult LoadProductsFromWeb()
    {
        ...
    }

    Le sens de LoadOperationResult.ServerUnavailable, LoadOperationResult.ParsingErroretc. est beaucoup plus explicite que, disons, se souvenant que le code 12 signifie que le serveur est en panne, et le code 13 - que les données ne peuvent pas être analysées.

  7. Utilisez des codes d'erreur lorsqu'ils font référence aux codes communs, connus de tous les développeurs qui travaillent dans le domaine spécifique. Par exemple, ne réinventez pas une valeur d'énumération pour HTTP 404 Not Found ou HTTP 500 Internal Server Error.

  8. Méfiez-vous des booléens. Tôt ou tard, vous voudrez non seulement savoir si une méthode spécifique a réussi ou échoué, mais pourquoi. Les exceptions et énumérations sont beaucoup plus puissantes pour cela.

  9. N'attrapez pas toutes les exceptions (sauf si vous êtes tout en haut de la pile). Si vous interceptez une exception, vous devez être prêt à la gérer. Tout attraper montre que vous ne vous souciez pas si votre code fonctionne correctement. Cela peut résoudre le problème "Je ne veux pas chercher maintenant comment résoudre ce problème", mais cela vous blessera tôt ou tard.

  10. En C #, ne renvoyez jamais d'exceptions comme celle-ci:

    catch (SomeException ex)
    {
        ...
        throw ex;
    }

    parce que vous cassez la pile. Faites ceci à la place:

    catch (SomeException)
    {
        ...
        throw;
    }
  11. Faites un effort lors de l'écriture de messages d'exception. Combien de fois j'ai vu quelque chose comme throw Exception("wrong data")ou throw Exception("shouldn't call this method in this context"). D'autres développeurs, y compris vous-même six mois plus tard, n'auraient aucune idée des données erronées et pourquoi ou pourquoi ne devrions-nous pas appeler une méthode dans un contexte, ni quel contexte précisément.

  12. N'affichez pas les messages d'exception à l'utilisateur. Ils ne sont pas attendus pour les gens ordinaires et sont souvent même illisibles pour les développeurs eux-mêmes.

  13. Ne localisez pas les messages d'exception. La recherche dans la documentation d'un message localisé est épuisante et inutile: chaque message doit être en anglais et en anglais uniquement.

  14. Ne vous concentrez pas exclusivement sur les exceptions et les erreurs: les journaux sont également extrêmement importants.

  15. Dans .NET, n'oubliez pas d'inclure des exceptions dans la documentation XML de la méthode:

    /// <exception cref="MyException">Description of the exception</exception>

    L'inclusion d'exceptions dans la documentation XML facilite grandement les choses pour la personne qui utilise la bibliothèque. Il n'y a rien de plus ennuyeux que d'essayer de deviner quelle exception pourrait être levée par une méthode et pourquoi.

    En ce sens¹, la gestion des exceptions Java offre une approche plus stricte et meilleure. Il vous oblige soit à traiter les exceptions potentiellement levées par les méthodes appelées, soit à déclarer dans votre propre méthode qu'il peut lever les exceptions que vous ne gérez pas, ce qui rend les choses particulièrement transparentes.


¹ Cela étant dit, je trouve la distinction Java entre les exceptions et les erreurs assez inutile et déroutante, étant donné que le langage a vérifié et décoché les exceptions. Heureusement, .NET Framework n'a que des exceptions et aucune erreur.

MainMa
la source
J'ai appris un peu la citation de cela, puis-je demander d'où vient la liste? Site ou expérience personnelle? Quoi qu'il en soit travail exceptionnel (hehe l'obtenir?).
Shelby115
@ Shelby115: la liste provient, dans l'ordre: Stack Exchange, expérience personnelle et Code Complete par Steve Mcconnell.
Arseni Mourzenko
Merci @MainMa qui est une excellente réponse! Je possédais Code Complete quand j'étais à l'université mais quelqu'un l'a volé. Je n'ai pas pu le lire.
James Jeffery
@JamesJeffery: alors empruntez la deuxième édition dans une bibliothèque, ou achetez-en une: c'est l'un des rares livres liés au développement qui en vaut vraiment la peine.
Arseni Mourzenko
@MainMa Je viens de commander sur Amazon, merci: DI possède également Clean Code et a totalement oublié le chapitre 7.
James Jeffery
1

Je pense que la liste de MainMa est très complète. Je vais juste en ajouter quelques-uns:

  1. Lisez l' article d' Eric Lippert sur la façon dont il classe les exceptions. Il est particulièrement important de ne pas intercepter les exceptions qui sont en réalité des bogues dans votre code. Fixez le code à la place!
  2. Si vous savez qu'une exception peut se produire ET que vous pouvez y faire quelque chose, gérez-la, mais limitez la portée de votre tentative de capture et interceptez l'exception spécifique que vous attendez. Autrement dit, ne faites pas cela:

public void Foo() {
    try {
        //get input from use
        //do calculations
        //open file
    }
    catch (Exception ex) {
       //handle exception
    }
}

Au lieu de cela, procédez comme suit:

public void Foo() {
    //get input from use
    //do calculations
    try {
        //open file
    }
    catch (FileOpenException ex) {
       //handle exception
    }
}
  • N'utilisez pas d'exceptions pour le flux de contrôle. Par exemple, ne lancez pas une exception ClientNotFoundException dans une boîte de dialogue de recherche (un client introuvable n'est pas exceptionnel dans cette situation) et attendez-vous à ce que le code appelant affiche un message «Aucun résultat trouvé» lorsque cela se produit.

  • N'avalez pas d'exceptions!

  • Gardez à l'esprit que vraiment gérer une exception ne peut signifier que 3 choses:

    1. Recommencez l'opération. Valable uniquement si le problème est transitoire.
    2. Essayez une alternative.
    3. Informez quelqu'un du problème. Valable uniquement si la notification est exploitable, ce qui signifie que l'utilisateur peut faire quelque chose.

    Si aucune de ces options ne s'applique, vous ne devriez probablement pas intercepter cette exception. Vous devez cependant l'enregistrer, puis annuler l'opération ou l'arrêter. Bien sûr, cela dépend de vos besoins en termes d'exactitude par rapport à la robustesse.

Mike
la source