web-dev-qa-db-fra.com

Comment puis-je ajouter un message à une exception sans perdre aucune information en C #?

J'ai le code suivant:

catch(Exception ex)
{
    throw new FatalException("An error occurred while trying to load the XSLT file.", ex);
}

Cela engloutit malheureusement l'exception. Je peux résoudre ce problème en procédant comme suit:

catch(Exception ex)
{
    throw;
}

Mais j'aimerais toujours inclure le message personnalisé pour obtenir de l'aide sur la journalisation des événements.

Comment ajouter ce message à l'exception sans perdre aucune information? (symboles de trace/débogage de pile, etc.)

54
Codeman

Si vous avez juste besoin d'ajouter des informations à l'exception d'origine, comme un message lisible par l'utilisateur ou des détails spécifiques qui vous seront utiles pour retrouver l'erreur mais qui ne seront pas utiles à l'utilisateur final, vous pouvez utiliser la propriété Data de l'exception, qui est un dictionnaire de paires clé/valeur.

Nous l'utilisons largement pour enregistrer des informations telles que le rapport en cours d'exécution ou le fichier en cours de traitement afin que les opérations puissent déterminer ce qui se passait exactement au moment de l'erreur. L'utilisateur n'a pas besoin de ces détails car il travaille directement avec la cause de l'échec.

Vous pouvez également l'utiliser pour transmettre un message en texte brut qui a du sens pour l'utilisateur. Le seul problème est que vous devrez effectuer des travaux supplémentaires dans votre infrastructure de journalisation ou votre interface utilisateur final afin d'extraire les données et de les rendre utiles au consommateur.

Par exemple, vous pourriez faire:

catch (Exception ex)
{
    ex.Data.Add("UserMessage", "An error occurred while trying to load the XSLT file.");
    throw;
}

Ensuite, dans le code côté client, vous pouvez tester pour voir si UserMessage existe et, le cas échéant, le présenter à l'utilisateur au lieu de l'exception:

catch (Exception ex)
{
    if (ex.Data.Contains("UserMessage"))
    {
        MessageBox.Show(ex.Data["UserMessage"].ToString());
    }
    else
    {
        MessageBox.Show(ex.Message);
    }
}
68
competent_tech

Cette exception d'origine est toujours là.

Lorsque vous effectuez la journalisation de votre exception, l'exception que vous recevez sera l'exception FatalException que vous avez créée avec votre message. L'exception d'origine se trouve dans ex.InnerException. Vous pouvez continuer à parcourir InnerException jusqu'à ce qu'il soit nul pour obtenir toutes les informations de trace de pile, etc.

15
krillgar

Bref, ne le faites pas.

Je suis sûr que vous pourriez trouver un moyen de contourner cela avec un peu de réflexion, mais je voudrais fortement vous mettre en garde contre cela. Cela va à l'encontre de la conception d'origine des exceptions dans .NET. Les exceptions ne sont pas seulement là pour aider à la journalisation, elles fournissent des informations sur la cause d'origine d'une défaillance d'application.

L'utilisation de la première option est généralement préférée car elle conserve la trace de pile de l'exception d'origine mais vous permet de fournir des informations supplémentaires en les enveloppant dans une exception distincte. Dans mon propre code, chaque fois que je journalise des exceptions, ma fonction de journalisation récurrente via la propriété InnerException pour trouver toutes les informations utiles possibles sur l'erreur.

1
p.s.w.g