Question

Depuis que Microsoft a introduit les blocs d’application, je rencontre des personnes qui utilisent le Bloc d'application de gestion des exceptions . J'ai récemment regardé de plus près moi-même et résumerais les fonctionnalités de base comme suit (sautez le bloc suivant si vous savez déjà ce qu'il fait):

  

Le bloc d’application de gestion des exceptions vise à centraliser et à rendre entièrement configurable avec les fichiers de configuration le tâches de gestion des exceptions clés :

     
      
  • Journalisation d'une exception
  •   
  • Remplacement d'une exception
  •   
  • Emballage d'une exception
  •   
  • Propager une exception
  •   
  • etc.
  •   
     

La bibliothèque le fait en vous demandant de modifier vos blocs catch comme suit:

try
{
  // Run code.
}
catch(DataAccessException ex)
{
    bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Policy");
    if (rethrow)
    {
        throw;
    }
}
     

Basé sur ce qui est spécifié dans app.config pour le nom de la politique ( voir ici pour les documents ), HandleException sera soit ...

     
      
  • lève une toute nouvelle exception (remplace l'exception d'origine)
  •   
  • encapsulez l'exception d'origine dans une nouvelle et jetez-la
  •   
  • avaler l'exception (c'est-à-dire ne rien faire)
  •   
  • avez-vous relancé l'exception d'origine
  •   
     

De plus, vous pouvez également le configurer pour qu'il fasse plus de choses au préalable (par exemple, enregistrez l'exception).

Maintenant, voici mon problème: je ne vois absolument pas en quoi il peut être bénéfique de le rendre configurable si une exception est remplacée, encapsulée, avalée ou retranscrite. D'après mon expérience, cette décision doit être prise au moment de l'écriture du code, car vous devrez généralement modifier le code environnant ou le code appelant lorsque vous modifierez le comportement de gestion des exceptions.

Par exemple, votre code commencera probablement à se comporter de manière incorrecte lors de la reconfiguration de telle sorte qu'une exception levée à un moment donné soit maintenant avalée au lieu d'être renvoyée (il peut y avoir du code après le bloc catch qui ne doit pas être exécuté lorsque se produit). Il en va de même pour tous les autres changements possibles dans la gestion des exceptions (par exemple, remplacer - > retransmettre, avaler - > envelopper).

En résumé, le blocage de la gestion des exceptions résout des problèmes qui n'existent pas dans la pratique. La journalisation des exceptions et le bit de notification sont acceptables, mais tous les autres éléments ne constituent-ils pas un exemple parfait pour la sur-ingénierie?

Était-ce utile?

La solution

Si vous utilisez des exceptions pour le flux de contrôle, vous souhaitez éviter la gestion des exceptions basée sur des stratégies.

Mais dans le cas des exceptions que vous souhaitez traiter comme non récupérables (une tâche en arrière-plan a échoué, le socket a été déconnecté, le fichier a été supprimé, etc.), vous souhaiterez peut-être une gestion des exceptions configurable et basée sur des règles. .

Par exemple, si vous développez une API, vous voudrez peut-être que chaque fonction de votre API ne lève que les exceptions standard ( ArgumentException , etc.), ainsi que votre propre bibliothèque. exception dans le cas d'une exception interne non standard (par exemple, une MyLibraryException ). Dans ce type de cas, tout ce qui compte est que quelque chose ne fonctionne pas correctement. Vous ne choisissez pas l'exception et ne déterminez pas ce qui n'a pas marché. Vous reconnaissez simplement le fait que quelque chose a mal tourné et que vous êtes censé faire quelque chose maintenant.

Ce élément devrait être configurable, car ce que vous faites importe peu. Afficher une boîte de message à l'utilisateur? Modal ou non modal? Connectez-vous l'exception? Comment voulez-vous enregistrer l'exception? Appeler un service Web de journalisation? Ajouter à un fichier journal? Écrire dans le journal des événements Windows? Insérer une entrée dans la base de données? Insérer une entrée dans deux bases de données? Cela n'a pas vraiment d'importance pour le reste de votre application. Le choix de la manière de gérer une exception est complètement orthogonal au reste de l’application.

(D'un autre côté, ce n'est pas ainsi que j'aborderais la gestion des exceptions configurable basée sur des règles. Je privilégierais plutôt un style AOP, tel que l'enregistrement d'un intercepteur d'enregistreur d'exceptions dans le conteneur.)

Autres conseils

Je rencontre ce problème lorsque je développe des fonctions n’ayant pas d’état récupérable. Je pense que cette gestion des exceptions guidée par des règles est réellement utile et garantit que tous les autres développeurs faisant partie de ce projet adhèrent à une norme pour les exceptions non récupérables.

Je suis d'accord avec les affiches ci-dessus, vous voudrez peut-être éviter les exceptions basées sur des règles si vous les utilisez pour contrôler les flux.

Je suis d'accord avec l'affirmation selon laquelle "le blocage de la gestion des exceptions résout des problèmes qui n'existent pas réellement dans la pratique". J'ai utilisé le bloc depuis sa sortie et j'ai rarement l'impression de vraiment gagner beaucoup en l'utilisant. Eh bien, peut-être un peu mal à la tête. :)

Avant de commencer, je dois admettre que j'aime bien le Exception Shielding at WCF Limites de service . Cependant, cela a été ajouté assez récemment, n'implique aucun code - uniquement des attributs et une configuration, et ne correspond pas à la manière dont le bloc est vendu. C’est ce que montre Microsoft à l’aide de http://msdn.microsoft.com/fr. -us / library / cc309250.aspx

 alt text

À mes yeux, ce qui précède est un contrôle de flux.

try
{
  // Run code.
}
catch(DataAccessException ex)
{
    bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Policy");
    if (rethrow)
    {
        throw;
    }
}

Lorsque vous combinez l'aspect contrôle de flux avec le code ci-dessus, vous n'êtes certainement pas donner un mauvais aperçu du code. faux . (Peu importe que la construction if (rethrow) n'offre pas beaucoup d'abstraction.) Cela peut rendre la maintenance plus difficile pour les développeurs non familiarisés avec les définitions de politique. Si le postHandlingAction dans le fichier de configuration est modifié (cela arrivera probablement à un moment donné), vous constaterez probablement que l'application se comporte de manière inattendue qui n'a jamais été testée.

Peut-être que je ne trouverais pas cela désagréable si le bloc ne gérait pas le contrôle de flux mais vous permettait simplement de chaîner des gestionnaires.

Mais peut-être pas. En fait, je ne me souviens pas d'avoir jamais été invité à:

  • ajoute une nouvelle fonctionnalité lors de la gestion d'une exception (par exemple, en plus de la journalisation dans le journal des événements, envoyez également un courrier électronique. En fait, le bloc de journalisation peut le faire tout seul si vous avez déjà enregistré l'exception vous-même. :) )
  • changez le comportement de gestion des exceptions (avaler, renverser ou lancer un nouveau) dans l'ensemble d'une "règle".

Je ne dis pas que cela ne se produit pas (je suis sûr que quelqu'un a une histoire!); Je pense simplement que le bloc d’application Exception Handling rend les programmes plus difficiles à comprendre et à gérer, ce qui l’emporte généralement sur les fonctionnalités fournies par le bloc.

Je ne pense pas que cela concerne l'ingénierie du tout. En réalité. le fait que les exceptions puissent passer par un gestionnaire central a été une bonne chose dans mon travail. J'ai eu des développeurs qui mangeaient toutes les exceptions - manipulés ou non, de manière à ce que cela ne déborde pas et que quelque chose d'inquiétant ne s'inquiète pas devant l'utilisateur final ou ne gâche pas sérieusement un service / démon lorsqu'il n'est pas attrapé.

maintenant, avec la politique, nous pouvons commencer la journalisation à tout moment sans avoir à redémarrer ou à éparpiller inutilement la logique de journalisation dans l'application. Maintenant, nous pouvons regarder les exceptions et autres sans mettre l'application hors ligne.

programmation intelligente si vous me demandez ...

Tout simplement: si vous voulez une gestion des exceptions différente dans votre code de version par rapport à votre code de débogage, alors ce serait utile.

À mon avis, l'utilisation du bloc Gestion des exceptions commence par une ligne de code dans votre bloc catch:

bool rethrow = ExceptionPolicy.HandleException (ex, "Politique d'accès aux données");

Une ligne de code - à quel point pouvez-vous être simple? Derrière la ligne de code, la stratégie, telle qu'elle est configurée, permet d’assigner / mettre à jour facilement une stratégie, sans avoir à recompiler le code source.

Comme cela a été mentionné, la stratégie d’exception peut en réalité exécuter de nombreuses actions, quelle que soit sa définition. Cacher la complexité derrière la ligne de code indiquée dans le bloc de capture est la raison pour laquelle je vois une valeur réelle.

Je dirais complexe, mais pas trop sophistiqué. Donc, je pense que de gros bénéfices seront perçus pendant la maintenance lorsque vous aurez besoin de changer votre façon de gérer / consigner les exceptions en ayant la possibilité de changer facilement de configuration, tout en conservant la même ligne de code source.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top