7
votes

Comment éviter les exceptions Captures Copy-coller dans .NET

Travailler avec .NET Framework, j'ai un service avec un ensemble de méthodes pouvant générer plusieurs types d'exceptions: myException2, myExc1, exception ... pour fournir un travail approprié pour toutes les méthodes, chacune d'entre elles contient des sections suivantes:

[WebMethod]
void Method1(...)
{
    try
    {
        ... required functionality
    }
    catch(MyException2 exc)
    {
        ... process exception of MyException2 type
    }
    catch(MyExc1 exc)
    {
        ... process exception of MyExc1 type
    }
    catch(Exception exc)
    {
        ... process exception of Exception type
    }
    ... process and return result if necessary
}


0 commentaires

6 Réponses :


6
votes

Si la manipulation des exceptions est exactement la même forte> dans toutes vos méthodes, vous pouvez faire quelque chose comme: xxx pré>

alors, vous pouvez simplement réécrire votre code client. Pour faire: P>

void Method1(int arg)
{
    // Leave out exception handling here...
    ... required functionality  
    ... process and return result if necessary
}

void Method2(string stringArg, int intArg)
{
    // Leave out exception handling here...
    ... required functionality  
    ... process and return result if necessary
}


6 commentaires

J'ai eu une idée similaire, mais le problème est que chaque méthode a un ensemble de paramètres différent (désolé, je n'ai pas mentionné cela dans la question initiale et ajouté des spécifications récemment). Voici exemple de méthodes Signatures: Méthode String1 (String); Méthode nul2 (chaîne, int, int), etc ...


@Budda: Cela n'a pas d'importance - ça va bien fonctionner, car Lambdas peut passer dans tous les arguments, la façon dont je l'ai écrite.


@Budda: J'ai édité ma réponse pour démontrer :) Cela fonctionne pour n'importe quel nombre d'arguments dans les méthodes ...


Merci. Mais dans ce cas, nous avons besoin de méthode supplémentaire pour chaque "myMethodx", non? J'éviterais cela ... et cela peut être réalisé avec des méthodes anonymes, quelque chose comme ceci: cela.CallService (() => {... Fonctionnalité requise}); Sans définition de méthode séparée ... non? :) Merci encore.


@ Budda: Oui, vous pouvez éviter la méthode entièrement, si vous n'en avez pas besoin. J'essayais juste de porter vos exemples. Vous avez beaucoup de flexibilité ici ...


@Budda: Vous pouvez également utiliser une méthode anonyme avec Lambdas.



-3
votes

Je sais que c'est une mauvaise pratique, mais si vous avez exactement la même manipulation d'erreurs dans chaque déclaration de capture, lorsque pourquoi ne pas simplement utiliser le dernier relevé de capture comme une capture tout?

Cela assume bien sûr toutes vos exceptions héritées de l'exception.


4 commentaires

Je ne suis pas - je ne suis que curieux de savoir pourquoi vous auriez exactement la même gestion d'erreur dans plusieurs déclarations de capture, car le point d'avoir plusieurs captures est que vous gérez vos exceptions différemment ...


J'ai exactement la même façon de manipuler afin de fournir le même traitement d'erreur pour toutes les méthodes.


Je pense que vous avez mal compris la question. Si je comprends bien: dans l'une de ses méthodes, chaque bloc Catch {} n'a pas la même manipulation. Ce qu'il a est le même ensemble de blocs de capture {} et de manipulation sur plusieurs méthodes


Vous avez raison, je n'ai pas saisi la pièce dans la question initiale concernant plusieurs méthodes. Excuses.



5
votes

Pourquoi ne pas simplement factoriser le code dans une méthode d'assistance pour vous faire pour vous (vous pouvez ajouter toutes les nouvelles exceptions dont vous avez besoin à l'avenir vers ManiptionException également, ce qui le rend assez évolutif)? < Pré> xxx


12 commentaires

DCP, pourquoi ré-lancez-vous une exception après avoir appelé à HeangException (e)?


Ce modèle violerait défiant la règle d'analyse de code de Microsoft "Ne pas attraperait des types d'exception généraux" msdn.microsoft.com/en-us/library/ms182137 (v = vs.90) .aspx


@chilltemp - Allez, le ne pas répéter votre règne d'auto a une priorité beaucoup plus élevée.


@Budda - La réthrow est donc l'appelant peut gérer l'exception. Si cela n'est pas nécessaire, le repère pourrait être retiré, mais nous souhaitons normalement laisser l'exception se propager ainsi que l'appelant sait que quelque chose a échoué.


@CHILLITEMP - Je pense que l'idée de la règle de microscil est que vous préférez gérer des exceptions spécifiques (si vous savez quelles exceptions vous attendez) et prenez l'action appropriée par opposition à l'utilisation de captures (exception e). Dans ce cas cependant, nous prenons l'action spécifique dans la méthode de la ManneException. Nous sommes donc vraiment adhérant à l'esprit de la règle, nous faisons simplement cela un peu différemment pour permettre la réutilisation du code, qui, comme @ Machaospandion, est vraiment une priorité plus élevée.


Merci, ces méthodes sont les plus élevées dans Webservice ... Donc, personne ne s'intéresse à la propagation ici.


Cela relève également des exceptions qui ont été traitées dans la gestion de la gestion.


@ODrade - Voir mon commentaire précédent à @budda. Souvent, le temps repoussé est le comportement souhaité. Ce n'est pas parce que nous avons "manipulé" l'exception ne signifie pas nécessairement que nous ne devrions pas laisser retirez-vous à l'appelant. Cela dépend des circonstances.


@Chaospandion: J'ai vu ce modèle exact utilisé de nombreux endroits dans toute la société que je travaille. Il comprend presque toujours d'autres mauvaises pratiques telles que «lancer ex» dans le gestionnaire d'exception commune. Je conviens que cette règle n'est pas valable dans tous les cas, mais une expérience personnelle m'a conduit à la méfiance des gestionnaires d'exception communs. Faites un gestionnaire d'exception commun pour chaque type d'exception, pas un gestionnaire pour les gouverner tous. (Et oui, je violais cette règle d'analyse de code tout le temps. Je ne fais tout simplement pas la promotion comme un bon modèle.)


@DCP: Pourquoi gérer l'exception si vous allez retirer 100% d'entre eux? Il aurait plus de sens de reproduire de manière conditionnelle l'exception si la méthode de la ManneException ne pouvait pas le gérer. Peut-être devrait-il retourner un bool.


@chilltemp - Je le fais habituellement au niveau de la classe. Je pense que c'est juste une question d'utiliser correctement la technique. Vous pouvez faire des choses stupides ou abuser de toute technique. J'ai utilisé ce modèle sur et j'aime aussi que la logique de gestion des erreurs est centralisée.


@chilltemp, @DCP - comme toujours, pensez avant de casser une règle commune. N'oubliez pas que les plus gros sauts du développement technologique viennent d'aller contre le grain.



2
votes

Je regarderais de près ce que vous faites pour "traiter" ces exceptions. Il y a de bonnes chances que vous n'ayez pas besoin de blocs de capture du tout et que vous devriez autoriser les exceptions à propager.


3 commentaires

Ces méthodes sont [WebMethod] de Web-service et ils devraient toujours retourner quelque chose de significatif au client. Toutes les sections de traitement des exceptions génèrent un objet "Erreur", qui est sérialisée en format XML et est envoyé au client. Votre suggestion m'a donné une idée d'optimiser la génération d'objets d'erreur ... il peut être mis en œuvre avec un motif d'usine ... de la manière suivante: attrape (exception exc) {erreur myerror = myerror.generateRorrobject (exc); ... processus (erreur); } Merci.


@Budda: 1) C'est bien de savoir. Dis si la prochaine fois. 2) Vous devriez lancer SOAPException avec le détail défini pour renvoyer une faute de savon.


J'ai besoin d'envoyer un message dans certains formats personnalisés et une exception de savon ne correspond pas :)



1
votes

Dans un éclat soudain de geekiness (et pour montrer ce que vous pourriez, mais très probablement ne devrait pas et ne veut pas ne pas faire): vous pouvez rendre le tout plus composable et réutilisable en générant des fonctions à la volée qui contiennent la manutention de l'exception logique: xxx

Vous pouvez maintenant implémenter et réutiliser un gestionnaire spécifique de type exceptionnel quelque part et les composer dans la manipulation d'exception d'une autre méthode.

Pour supprimer la redondance Vous pouvez écrire une fonction d'assistance qui ajoute les fonctions de gestionnaire d'exception «typique» à ce que vous souhaitez appeler et appelez cette méthode décorée.


0 commentaires

0
votes

Utilisation de la méthode d'allaitez à partir de REED COPSEY:

T CallService<T>(Func<T> callback) { /* ... */ }


0 commentaires