2008-09-28 4 views
34

Comment avez-vous utilisé la propriété Exception.Data dans les projets C# sur lesquels vous avez travaillé? Je voudrais des réponses qui suggèrent un modèle, plutôt que ceux qui sont très spécifiques à votre application.Utilisation de Exception.Data

Répondre

17

Le journal des exceptions que j'utilise a été modifié pour écrire tous les éléments de la collection de données. Ensuite, pour chaque exception rencontrée que nous ne pouvons pas diagnostiquer à partir de la pile d'exceptions, nous ajoutons toutes les données dans la portée de cette fonction, envoyons une nouvelle construction et attendons qu'elle se reproduise. Je pense que nous sommes optimistes en ce sens que nous ne le mettons pas dans toutes les fonctions, mais nous sommes pessimistes en ce sens que nous ne le retirons pas une fois que nous avons résolu le problème.

14

Je l'ai utilisé quand j'ai su que l'exception que je créais allait devoir être sérialisée. En utilisant Reflector un jour, j'ai découvert que Excepion.Data était coincé dans les flux de sérialisation. Par conséquent, si j'ai des propriétés sur une classe d'exception personnalisée qui sont déjà sérialisables, je les implémente sur la classe dérivée et utilise l'objet de données sous-jacent comme mécanisme de stockage plutôt que de créer des champs privés pour contenir les données. Si les propriétés de mon objet d'exception personnalisé nécessitent une sérialisation plus avancée, je les implémente généralement à l'aide de champs privés de support et gère leur sérialisation dans la classe dérivée.

Conclusion, Exception.Data vous offre la sérialisation gratuitement en y insérant vos propriétés - mais souvenez-vous simplement que ces éléments doivent être sérialisables!

+6

Le seul problème avec cette approche est que la propriété des données est définie comme virtuelle, ce qui signifie que vous ne devriez pas l'utiliser dans les constructeurs d'exception (rapporté par FxCop).Ce qui pose un problème si vous souhaitez que le constructeur définisse vos propriétés personnalisées liées au dictionnaire de données. –

+0

Un point valide; cependant, il peut être atténué de deux manières: 1. Ne fournissez pas un constructeur pour définir ces propriétés (et à son tour faire l'appel virtuel.) Plutôt, fournissez uniquement des accesseurs de propriété get/set et utilisez la syntaxe d'initialisation d'objet. 2. Marquez votre classe d'exception comme scellée. Tandis que "scellé" me frotte généralement dans le mauvais sens, dans de nombreux cas où une classe d'exception personnalisée est concernée, elle peut être parfaitement légitime. –

+1

Ou ne vous en souciez pas, l'appel de méthodes virtuelles à partir de constructeurs ne vous cause que des problèmes dans des cas inhabituels –

9

Je l'ai utilisé pour capturer des informations sur l'état au moment de l'exception de la portée englobante que l'exception parcourt la pile. Des éléments tels que le nom de fichier à l'origine de l'exception ou la valeur de certains ID permettant de localiser le problème.

En haut niveau le plus dans une application web, je tends aussi ajouter une grande partie de l'information de demande comme le RawUrl, les biscuits, le référenceur ...

Pour plus de détails ici est my blog on the topic:

Plutôt que d'attendre que des problèmes surviennent, j'ajoute ce code partout où une exception peut survenir liée à quelque chose d'extérieur, par exemple un nom de fichier, ou une URL qui était en cours d'accès, ... En d'autres termes, toutes les données qui aideront à reproduire le problème.

8

Puisqu'aucune des réponses n'inclut de code. Quelque chose qui pourrait être utile comme un ajout à cette question est de savoir comment réellement regarder le dictionnaire .Data. Comme ce n'est pas un dictionnaire générique et qu'il ne renvoie que IDictionary

foreach(var kvp in exception.Data), le type de kvp sera en fait object. Cependant de la MSDN il y a un moyen facile de parcourir ce dictionnaire:

foreach (DictionaryEntry de in e.Data) 
    Console.WriteLine(" Key: {0,-20}  Value: {1}", 
          "'" + de.Key.ToString() + "'", de.Value); 

Je ne sais pas vraiment ce que l'argument de format , -20 signifierait, peut-être prendre (20)? Digressing ... ce code peut être très utile dans un enregistreur d'erreur commun pour dérouler ces données. Une utilisation plus complète serait similaire à:

var messageBuilder = new StringBuilder(); 

do 
{     
    foreach (DictionaryEntry kvp in exception.Data) 
     messageBuilder.AppendFormat("{0} : {1}\n", kvp.Key, kvp.Value); 

    messageBuilder.AppendLine(exception.Message); 


} while ((exception = exception.InnerException) != null); 

return messageBuilder.ToString();