2010-10-11 5 views
4

Je souhaite utiliser ELMAH pour consigner une exception (sans la lancer tout le long de la pile d'appels) et enregistrer la totalité de la pile d'appels.Comment enregistrer une exception avec une pile d'appels complète?

code Exemple:

protected void Page_Load(object sender, EventArgs e) 
    { 
     DoSomething(); 
    } 

    private void DoSomething() 
    { 
     try { TrySomething(); } 
     catch (Exception ex) { LogException(ex); } 
    } 

    private void TrySomething() 
    { 
     throw new NotImplementedException(); 
    } 

    public static void LogException(Exception ex) 
    { 
     var currentStack = new System.Diagnostics.StackTrace(true); 
     Elmah.ErrorSignal.FromCurrentContext().Raise(ex); 
    } 

Maintenant, dans la méthode LogException je peux voir la pile d'appel me disant DoSomething() appelé TrySomething(), et qui a jeté l'exception, mais je ne vois pas l'appel pile me montrant Page_Load() appelé DoSomething(). Je veux être en mesure de voir la pile d'appels complète.

Exemple de ce que ex.StackTrace ressemble à l'intérieur méthode LogException:

at WebApplication1._Default.TrySomething() in C:\Projects\test\GeneralTests\WebApplication1\Default.aspx.cs:line 26 
at WebApplication1._Default.DoSomething() in C:\Projects\test\GeneralTests\WebApplication1\Default.aspx.cs:line 20 

je peux obtenir la pile d'appel complet de System.Diagnostics.StackTrace(), par exemple:

at WebApplication1._Default.LogException(Exception ex) 
at WebApplication1._Default.DoSomething() 
at WebApplication1._Default.Page_Load(Object sender, EventArgs e) 
[snip] 

(et je peux obtenir les numéros de ligne et les détails du fichier source en parcourant chaque image de StackTrace)

Mais comment puis-je injecter ceci dans l'exception ou élever une nouvelle exception avec cette pile d'appels queue? Y a-t-il une manière élégante de faire ceci? Ai-je manqué quelque chose de vraiment évident ?!

+0

Découvrez ces réponses sur des questions connexes qui permettent de mieux comprendre les raisons pour lesquelles vous ne recevez pas la pleine pile d'appel: http://stackoverflow.com/a/6094700/945456 et http://stackoverflow.com/a/24297684/945456 –

Répondre

1

Lorsque l'application est compilée sans indicateurs de débogage, la pile n'est pas nécessairement conservée en exécution. Vous pouvez uniquement garantir chaque élément enregistré en ajoutant try/catch à chaque méthode.

+0

Voulez-vous dire que les appels de méthode peuvent être insérés dans la séquence d'exécution? Sinon, je ne suis pas sûr de comprendre ce que vous dites: la pile d'appels doit être conservée! – Alex

+0

Oui, je pense que c'est inlining. Try/catch le contournera, ou construira toujours en mode debug. – cjk

+0

@Alex: il signifie que le compilateur (et le JIT) optimise souvent votre code en ajoutant des méthodes (bien que vous puissiez l'empêcher en utilisant MethodImplAttribute); Dans ce cas, vous n'obtiendrez pas une trace de pile complète. – ShdNx

1

Avez-vous regardé les résultats de Exception.ToString()? Il comprend une trace de pile. Inclut-il le type que vous recherchez?

+2

ex.StackTrace est une représentation sous forme de chaîne de la pile d'appels actuelle (interne), mais elle ne me montre pas la pile en dehors de l'exception. Je vais mettre à jour le corps de la question avec les résultats de ex.StackTrace et ce que je suis après – Alex

4

Vous pouvez faire quelque chose comme ça pour obtenir la pile complète quand un ocurrs d'erreur:

var currentStack = new System.Diagnostics.StackTrace(true); 
return currentStack.ToString(); 
Questions connexes