27 votes

Gérer les exceptions, est-ce un bon moyen?

Nous sommes aux prises avec une politique de correctement gérer les exceptions dans notre application. Voici nos objectifs pour elle (résumé):

  • Ne traiter que les exceptions spécifiques.
  • Gérer seules exceptions que vous pouvez corriger
  • Connecter qu'une seule fois.

Nous sommes venus avec une solution qui implique un générique Spécifique de l'Application de l'Exception et de la marche comme ça dans un morceau de code:

try {
  // Do whatever
}
catch(ArgumentNullException ane)
{
  // Handle, optinally log and continue
}
catch(AppSpecificException)
{
  // Rethrow, don't log, don't do anything else
  throw;
}
catch(Exception e)
{
  // Log, encapsulate (so that it won't be logged again) and throw
  Logger.Log("Really bad thing", e.Message, e);
  throw new AppSpecificException(e)
}

Toute exception est enregistré et s'est ensuite tourné vers un AppSpecificException de sorte qu'il ne sera pas enregistré de nouveau. Il finira par atteindre la dernière station de gestionnaire d'événements qui auront à traiter avec elle si elle a pour.

Je n'ai pas tellement d'expérience avec la gestion des exceptions modèles... Est-ce une bonne façon de résoudre nos objectifs? Les principaux inconvénients ou big red mises en garde?

Remarque: l'Un des inconvénients de cette est que, après la première prise de vous perdre la capacité de gérer une exception spécifique (si vous appelez une méthode qui appelle une autre méthode et de la deuxième, déclenche une exception vous n'êtes pas capable de le gérer) mais je l'ai trouvé, je n'ai jamais fait ça de toute façon ... je n'gérer les exceptions avec un niveau de profondeur ...

58voto

John Saunders Points 118808

Si vous vous connectez à l'exception trop près de l'heure, c'est la première levée, vous ne serez pas à l'enregistrement de l'intégrale de la pile.

Gérer les exceptions (qui est, les corriger), aussi près que possible du moment où ils ont été jetés. Recueillir des informations sur le contexte, dès que possible, quand ils ont été jetés. Mais permettre des exceptions à se propager jusqu'à l'endroit où ils peuvent être manipulés. La journalisation est un dernier recours sorte de manipulation, de sorte qu'il devrait se produire dans les couches externes de l'application des sous-systèmes.

Cela devrait éliminer la nécessité d'une application spécifique exception utilisée comme un marqueur de ne pas le journal d'une exception qui ne devrait pas avoir été pris pour commencer.

6voto

Eric Lippert Points 300275

Voir les commentaires de cet article de blog:

http://blogs.msdn.com/ericlippert/archive/2010/03/04/too-much-reuse.aspx

Il y a là une excellente discussion sur certains des pièges de la gestion des exceptions.

5voto

Justin Points 42106

N'enregistrez pas une exception, puis relancez-la - il est de la responsabilité des appelants de gérer / enregistrer toutes les exceptions que vous générez.

Ne capturez qu'une exception pour la gérer (par exemple pour la journaliser) ou ajoutez des informations spécifiques au contexte.

0voto

OverLex Points 1591

C'est une approche commune pour résoudre l'exception de la manipulation de problème (de plus spécifique, moins précis).

Il suffit de garder à l'esprit que le fait d'avoir un générique spécifique à l'application de l'exception pour attraper tout ce qui se passe au sein de cette application/méthode n'est pas une bonne idée si vous voulez attraper des problèmes spécifiques. Finalement essayer de l'étendre avec plus d'exceptions spécifiques.

Renvoi des exceptions est bon, le mieux est de déclarer la méthode de jeter certaines exceptions et que les appelants gérer. De cette façon, vous aurez à créer moins de code et vous pourrait centraliser certains contrôles.

0voto

lestival Points 34

Première option pour résoudre le problème de trace de pile:

 class AppSpecificException : ApplicationException
{
    public string SpecificTrace { get; private set; }
    public string SpecificMessage { get; private set; }

    public AppSpecificException(string message, Exception innerException)
    {
        SpecificMessage = message;
        SpecificTrace = innerException.StackTrace;
    }

}
 

J'ai dû écrire un exemple pour comprendre la question et vérifier le problème de stacktrace, c'est le code pour moi, mettre l'attention sur la méthode button2_click, enfin ma zone de texte affiche la chaîne de crash et la stacktrace:

     private String internalValue;

    private void Operation1(String pField)
    {
        if (pField == null) throw new ArgumentNullException("pField");
        internalValue = pField;
    }

    private void Operation2(Object pField)
    {
        if (pField == null) throw new ArgumentNullException("pField");
        internalValue = Convert.ToInt32(pField).ToString();
    }

    private void Operation3(String pField)
    {
        if (pField == null) throw new ArgumentNullException("pField");
        internalValue = pField;
        Operation2(-1);
    }


    /// <exception cref="AppSpecificException"><c>AppSpecificException</c>.</exception>
    private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            Operation1("One");
            Operation2("Two");
            Operation3("Three");
            MessageBox.Show(internalValue);
        }
        catch (ArgumentNullException ex)
        {
            textBoxException.Text = ex.Message + (char) 13 + (char) 10 + ex.StackTrace;
        }
        catch (AppSpecificException ex)
        {
            //textBoxException.Text = ex.Message + (char)13 + (char)10 + ex.StackTrace;
            throw;
        }
        catch (Exception ex)
        {
            textBoxException.Text = ex.Message + (char)13 + (char)10 + ex.StackTrace;                    
            throw new AppSpecificException("crash", ex);
        }

    }

    private void button2_Click(object sender, EventArgs e)
    {
        try
        {
            button1_Click(sender, e);
        }
        catch (AppSpecificException ex)
        {
            textBoxException.Text = ex.SpecificMessage + (char) 13 + (char) 10 + ex.SpecificTrace;
        }
    }
 

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