如何使用完整调用堆栈记录异常?

时间:2010-10-11 11:50:51

标签: c# error-handling elmah callstack

我想使用ELMAH来记录异常(不会将其一直抛到调用堆栈上)并记录整个调用堆栈。

示例代码:

    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);
    }

现在,在LogException方法中,我可以看到调用堆栈告诉我DoSomething()调用TrySomething(),并抛出异常,但是我看不到调用堆栈显示我的Page_Load()调用了DoSomething()。我希望能够看到完整的调用堆栈。

在LogException方法中ex.StackTrace的示例:

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

我可以从System.Diagnostics.StackTrace()获取完整的调用堆栈,例如:

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

(我可以通过遍历StackTrace的每一帧来获取行号和源文件详细信息)

但是如何将此注入Exception或使用此调用堆栈详细信息引发新的Exception?有一种优雅的方式来做到这一点?我错过了一些非常明显的东西吗?!

3 个答案:

答案 0 :(得分:4)

当出现错误时,您可以执行以下操作来获取完整堆栈:

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

答案 1 :(得分:1)

在没有调试标志的情况下编译应用程序时,堆栈不一定在执行中保留。您只能通过向每个方法添加try / catch来保证每个项目都被记录。

答案 2 :(得分:1)

你看过Exception.ToString()的结果吗?它包括堆栈跟踪。它包括你正在寻找的那种吗?