27 votes

Code de la méthode principale entièrement dans try / catch: est-ce une mauvaise pratique?

Habituellement, je mets tout mon code de méthode Main dans un bloc try / catch comme ceci:

 public static void Main(string[] args)
{
   try
   {
      // code
   }
   catch (Exception e)
   {
      // code
   }
}
 

Je le fais juste au cas où des exceptions parviendraient à s'échapper du reste de la logique du programme, me permettant ainsi de faire quelque chose, comme l'afficher sur la console, le connecter à un fichier, etc. Cependant, on m'a dit que c'est une mauvaise pratique.

Pensez-vous que ce soit une mauvaise pratique?

35voto

Cody Gray Points 102261

Emballage tout morceau de code dans un try/catch bloc sans une bonne raison est une mauvaise pratique.

Dans l' .NET modèle de programmation, des exceptions doivent être réservés pour des cas vraiment exceptionnels ou des conditions. Vous devez seulement pour attraper les exceptions que vous pouvez réellement faire quelque chose au sujet de. En outre, vous devriez ne devrait guère jamais attraper la base System.Exception classe (mais préférez plutôt pour attraper les plus spécifiques, issus des classes d'exception, vous pouvez gérer). Et devrait vraiment une exception inattendue être rencontrées au cours de votre programme d'exécution, vous devriez crash.

Évidemment, la réponse "correcte" aurait du être faite au cas par cas, en fonction de ce qui se passe à l'intérieur qu' // code de l'espace réservé dans votre catch bloc. Mais si vous allez avoir une règle générale ou les "meilleures pratiques", vous devriez toujours avoir une raison particulière pour intercepter des exceptions, pas juste envelopper l'ensemble de votre code dans un gigantesque try/catch bloc comme une question de cours sans y penser.

Notez que si vous êtes tout simplement en essayant d'attraper les exceptions non gérées susceptibles de se produire aux fins de l'exploitation forestière ou d'une erreur de déclaration, vous devriez être en utilisant l' AppDomain.UnhandledException événement. C'est une notification d'événement, afin de ne pas vous permettre de gérer ces exceptions, mais c'est le bon endroit pour mettre en œuvre votre journalisation ou les rapports d'erreurs après que votre demande est tombé en panne.


EDIT: Comme je l'ai été à rattraper le retard dans ma lecture de Raymond Chen excellent blog, "Le Vieux Chose de Nouveau", j'ai remarqué qu'il avait récemment publié un article sur un sujet similaire. C'est le propre des COM, plutôt que de la .NET Framework, mais les concepts généraux concernant le traitement des erreurs sont également applicables pour les deux environnements. Je pensais que je voudrais partager quelques joyaux de l'article ici, à l'appui de ma [apparemment très controversée] avis.

Historiquement, COM placé un géant try/except autour de votre serveur méthodes. Si votre serveur a rencontré ce qui serait normalement une exception non gérée, le géant try/except serait de l'attraper et de le transformer dans l'erreur RPC_E_SERVERFAULT. Il a ensuite marqué l'exception comme traité, de sorte que le serveur est resté en cours d'exécution, ce qui "l'amélioration de la robustesse en gardant le serveur qui exécute même quand il a rencontré un problème."

Rappelez-vous, c'était en fait un mauvais service.

Le fait qu'une exception non gérée s'est produite signifie que le serveur a été dans un état inattendu. Par la capture de l'exception et de dire, "Ne vous inquiétez pas, c'est du tout bon," en fin de compte vous laissant un corrompu serveur en cours d'exécution.

[ . . . ]

Attraper toutes les exceptions et de laisser le processus se poursuivre l'exécution suppose qu'un serveur peut récupérer d'une panne imprévue. Mais ce qui est absurde. Vous savez déjà que le serveur est unrecoverably toast: Il s'est écrasé!

Beaucoup mieux est de laisser le crash du serveur, de sorte que le fichier de vidage sur incident peuvent être capturées sur le point de défaillance. Maintenant vous avez une chance de découvrir ce qui se passe.

Vous pouvez [et] des lire l'article en entier ici sur son blog: Comment désactiver le gestionnaire d'exceptions qui COM "utilement" s'enroule autour de votre serveur.

6voto

harpo Points 17399

Si vous êtes en train de faire le plus intelligent chose que vous pouvez avec l'erreur, c'est une bonne pratique. C'est ce que try/catch est pour.

Si vous êtes juste de jeter l'erreur de distance (ou de leur enregistrement et de le jeter) — surtout si vous êtes en train de faire donc, quel que soit le type de l'exception — qui est considéré comme une mauvaise pratique.

Ceci peut soulever la question: que faire si le plus intelligent chose à faire est de connecter et de la jeter? Je veux dire que ce serait un cas exceptionnel. Mais dans la pratique, mon code d'affirmer le contraire. Je suppose que je vous adonner à un grand nombre de mauvaises pratiques.

4voto

Nathaniel Points 101

Je aggree avec 90% de ce que Cody dit. Il y a des situations similaires à la pluggin exemple où vous voudrez système de prise d'exceptions. Voici un autre exemple, considérons la consommation d'un service web WCF.

Objectif: Consommer le service et d'en disposer, même si une erreur est rencontrée. Permettre à l'erreur à bulle.

public static bool DoRemoteWebServiceWork()
{
    bool result;
    RemoteWebServiceClient client = new RemoteWebServiceClient();
    try
    {
        result = client.DoWork();
        client.Close();
    }
    catch (Exception)
    {
        client.Abort(); //dispose
        throw;//This service is critical to application function. The application should break if an exception is thrown.
        //could log end point and binding exceptions to avoid ignoring changes to the remote service that require updates to our code.
    }
    return result;
}

Objectif: Consommer le service et d'en disposer, même si une erreur est rencontrée. Éviter l'erreur de propagation.

public static bool DoRemoteWebServiceWork()
{
    bool result;
    RemoteWebServiceClient client = new RemoteWebServiceClient();
    try
    {
        result = client.DoWork();
        client.Close();
    }
    catch (Exception)
    {
        client.Abort(); //dispose
        //throw; //This service is auxiliary to the applications primary function. We have no influence over the service and therefore cannot fix it.
        //could log end point and binding exceptions to avoid ignoring changes to the remote service that require updates to our code.
    }
    return result;
}

1voto

Artur Mustafin Points 1381

Vraiment, oui, c'est une mauvaise pratique, à l'Exception pour l'utilisation de la classe

Vous devez prendre soin sur les types de une exception, qui ne coupe pas toutes les exceptions sur le bloc catch, les empêchant d'informer le système de l'erreur.

Exception de la classe est une classe de base, et, est une exception de niveau supérieur peut être atteint dans le code. L'utilisation de la plupart des Exceptions spécifiques dans le bloc catch, précisément, le seul qui, qui vous code soulève dans un try {...} catch{...} bloc, et seulement si elle peut être efficacement résolu à ce niveau (dans une fonction, où le bloc try.. catch est déclarée)

0voto

Leonidas Points 2059

Cela dépend de ce que vous faites si vous détectez une erreur. Si vous attrapez toutes les erreurs pour les gérer avec élégance - mauvaise pratique. Je dirais que c'est une mauvaise pratique même si vous ne vous connectez que là-bas - connectez-vous localement.

Si vous faites vraiment quelque chose pour récupérer l'erreur (par exemple, vous l'avez lancée vous-même et savez quoi faire à ce sujet) - je voterais bien :)

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