38 votes

Erreurs de programmation courantes en .Net lors de la gestion des exceptions ?

Quelles sont les erreurs les plus courantes que vous avez vues commettre lors du traitement des exceptions ?

Il semble que la gestion des exceptions soit l'une des choses les plus difficiles à apprendre à faire "correctement" en .Net. Surtout si l'on considère que la réponse actuellement classée n°1 à la question Les erreurs de programmation courantes à éviter pour les développeurs .NET ? est liée à la gestion des exceptions.

Nous espérons qu'en énumérant les erreurs les plus courantes, nous pourrons tous apprendre à mieux gérer les exceptions.

44voto

Eric Lippert Points 300275

Quelles sont les erreurs les plus courantes que vous avez vues commettre lors du traitement des exceptions ?

Je peux penser à beaucoup de choses.

Lisez d'abord mon article sur la catégorisation des exceptions en vexant , imbécile , fatal y exogène :

http://ericlippert.com/2008/09/10/vexing-exceptions/

Quelques erreurs courantes :

  • Défaut de traitement des exceptions exogènes.

  • L'incapacité à traiter les exceptions contrariantes.

  • Construction de méthodes qui lèvent des exceptions contrariantes.

  • Gérer les exceptions que vous ne pouvez en fait pas gérer, comme les exceptions fatales.

  • Gestion des exceptions qui cachent des bogues dans votre code ; ne traitez pas une exception stupide, corrigez le bogue pour qu'elle ne soit pas lancée en premier lieu.

  • Erreur de sécurité : passage en mode non sécurisé

    try
    {
      result = CheckPassword();
      if (result == BadPassword) throw BadPasswordException();
    }
    catch(BadPasswordException ex) { ReportError(ex); return; }
    catch(Exception ex) { LogException(ex); }
    AccessUserData();

    Vous avez vu ce qui s'est passé ? On est passé en mode non sécurisé. Si CheckPassword a lancé NetworkDriverIsAllMessedUpException, nous l'avons attrapé, enregistré et accéder aux données de l'utilisateur, que le mot de passe soit correct ou non . Passez en mode sans échec ; lorsque vous recevez une exception, supposez le pire.

  • Erreur de sécurité : production d'exceptions qui fuite d'informations sensibles directement ou indirectement.

    Il ne s'agit pas exactement de gérer les exceptions dans votre code, mais plutôt de produire des exceptions qui seront gérées par un code hostile.

    Une histoire amusante. Avant que .NET 1.0 ne soit livré aux clients, nous avons découvert un bogue qui permettait d'appeler une méthode qui générait l'exception "l'assemblage qui a appelé cette méthode n'a pas la permission de déterminer le nom du fichier". C:\foo.txt ". Super. Merci de me le faire savoir. Qu'est-ce qui empêche ladite assemblée d'attraper l'exception et d'interroger son message pour obtenir le nom du fichier ? Rien. Nous avons réparé ça avant de l'expédier.

    C'est un problème direct. Un problème indirect serait un problème que j'ai implémenté dans LoadPicture en VBScript. Il donne un message d'erreur différent selon que l'argument incorrect est un répertoire, un fichier qui n'est pas une image, ou un fichier qui n'existe pas. Ce qui signifie que vous pouvez l'utiliser comme un navigateur de disque très lent ! En essayant tout un tas de choses différentes, vous pourriez progressivement vous faire une idée des fichiers et des répertoires présents sur le disque dur de quelqu'un. Les exceptions doivent être conçues de telle sorte que si elles sont traitées par un code non fiable, ce code n'apprenne aucune information privée de l'utilisateur à partir de ce qu'il a fait pour provoquer l'exception. (LoadPicture donne maintenant des messages d'erreur beaucoup moins utiles).

  • Erreur de sécurité et de gestion des ressources : Les gestionnaires qui ne nettoient pas les ressources sont fuites de ressources qui attendent de se produire. Les fuites de ressources peuvent être utilisées comme déni de service les attaques par un code de confiance partiel hostile qui crée délibérément des situations générant des exceptions.

  • Erreur de robustesse : Les gestionnaires doivent Supposons que l'état du programme est perturbé à moins de traiter une exception exogène spécifique. Ceci est particulièrement vrai pour les blocs finally. Lorsque vous traitez une exception inattendue, il est tout à fait possible et même probable que quelque chose soit profondément perturbé dans votre programme. Vous n'avez aucune idée si l'un de vos sous-systèmes fonctionne et, si c'est le cas, si le fait de les appeler va améliorer ou aggraver la situation. Concentrez-vous sur l'enregistrement de l'erreur et la sauvegarde des données de l'utilisateur si possible et arrêtez-vous aussi proprement que possible. Supposez que rien ne fonctionne correctement.

  • Erreur de sécurité : les mutations temporaires de l'état global qui ont des répercussions sur la sécurité doivent être annulées avant tout code qui pourrait être hostile peut s'exécuter. Le code hostile peut s'exécuter avant Enfin, les blocs fonctionnent ! Voir mon article à ce sujet pour plus de détails :

http://blogs.msdn.com/ericlippert/archive/2004/09/01/224064.aspx

25voto

Anna Lear Points 13919

Rejeter les exceptions comme ça :

try 
{ 
   // some code here
}
catch(Exception ex)
{
   // logging, etc
   throw ex;
}

Cela tue la trace de la pile, ce qui la rend beaucoup moins utilisable. La manière correcte de relancer serait comme ceci :

try 
{ 
   // some code here
}
catch(Exception ex)
{
   // logging, etc
   throw;
}

12voto

Jay Riggs Points 30783

Attraper toutes les exceptions alors que dans de nombreux cas, vous devriez essayer d'attraper des exceptions spécifiques :

try {
  // Do something.
} catch (Exception exc) {
  // Do something.
}

Plutôt que :

try {
  // Do something.
} catch (IOException exc) {
  // Do something.
}

Les exceptions doivent être classées de la plus spécifique à la moins spécifique.

10voto

Carlos Loth Points 2083

Renvoi d'une exception avec un message sans signification.

try
{
    ...
}
catch (Exception ex)
{
   throw new Exception("An error ocurred when saving database changes").
}

Vous ne croirez pas combien de fois je vois du code comme celui-ci fonctionner en production.

9voto

Srikar Doddi Points 10611

Personne ne parle de voir des blocs de capture vides comme ceux-ci.....

 try{  
      //do something
    }
catch(SQLException sqex){  
        // do nothing  
    }

N'utilisez jamais non plus le traitement des exceptions pour créer des flux de méthodes alternatifs...

 try{  
     //do something  

 }catch(SQLException sqex){  

     //do something else  
 }

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