Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get variable values in my stack trace dump?

I maintain an application that sends me an email when an error occurs in the application. I dump the stack trace into the email, and it seems to work ok. The only thing missing is the values of the variables. I get all the calls and such, just never any variables. What am I missing in order to get these variable values dumped into the email too?

Below is the code I use to dump it into an email:

UtilityClass.SendEmail(shortNTID,
                       "[email protected]",
                       new string[] { "[email protected]" },
                       "MyApplication error has occured for user: " +
                            shortNTID + " (Main).",
                       "Message: " + ex.Message.ToString() +
                       " Source: " + ex.Source.ToString() +
                       " Target Site: " + ex.TargetSite.ToString() +
                       " Stack Trace: " + ex.StackTrace.ToString());

And here is the result in the email:

Message: Specified cast is not valid. Source: MyApplication Target Site: Void FindFormAndActivate(MyApplication.MDIParentForm, System.String, System.Object) Stack Trace: at MyApplication.UtilityClass.FindFormAndActivate(MDIParentForm frmMDIParentForm, String formName, Object parameter) at MyApplication.DashboardAlerts.NavigateToAssignment() at MyApplication.DashboardAlerts.utAlerts_MouseClick(Object sender, MouseEventArgs e) at System.Windows.Forms.Control.OnMouseClick(MouseEventArgs e) at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

EDIT

Some answers have suggested that I add the variable values myself to the email. How would I get those values though? This snippet of code that sends the email is not in the method that is failing. This is code that runs any time an exception occurs. If the exception isn't handled and corrected, I let it bubble up to the top of the thread a la Application.ThreadException += new ThreadExceptionEventHandler(HandleError); and the HandleError method is the one that makes this email call. It has no idea what the variables or parameters were for the method that caused the exception.

like image 466
richard Avatar asked Jun 02 '11 19:06

richard


People also ask

How do you view the value of a variable?

Hover over a variable to see its value. The most commonly used way to look at variables is the DataTip. When stopped in the debugger hover the mouse cursor over the variable you want to look at. The DataTip will appear showing you the value of that variable.


2 Answers

Instead of trying to put them in the stack trace, just add them to the string you're sending.

UtilityClass.SendEmail(shortNTID,
                   "[email protected]",
                   new string[] { "[email protected]" },
                   "MyApplication error has occured for user: " +
                        shortNTID + " (Main).",
                   "Message: " + ex.Message.ToString() +
                   " Source: " + ex.Source.ToString() +
                   " Target Site: " + ex.TargetSite.ToString() +
                   " Stack Trace: " + ex.StackTrace.ToString() +
                   " MyVar1 Value: " + MyVar1.ToString() +
                   " MyVar2 Value: " + MyVar2.ToString() +
                   " MyVar3 Value: " + MyVar3.ToString());

Edit:

Since the email is being sent outside the variables' scope, you're going to need to collect them when they're in scope and add them to the exception being thrown. I'm afraid I don't know much about the ThreadException object, but I'd create a custom exception that holds the values of those variables. You won't be able to automagically add them to the stack trace; that's not really what it's for. So, off the top of my head:

public class CustomException : Exception
{
    public string MyVar1 { get; private set; }
    public string MyVar2 { get; private set; }
    public Exception OriginalException { get; private set; }

    public CustomException(Exception original, string myVar1, string myVar2)
    {
        MyVar1 = myVar1;
        MyVar2 = myVar2;
        OriginalException = original;
    }
}

Later, deep in your code:

try
{
    //code that might throw exceptions
}
catch (Exception e)
{
    throw new CustomException(e, myVar1, myVar2);
}

The fact that you're preserving the original exception by keeping it in the OriginalException property should (hopefully) also preserve the original stack trace.

like image 60
Justin Morgan Avatar answered Oct 02 '22 13:10

Justin Morgan


The StackTrace property is just the call graph at the point the exception occurred. If you're interested in the state of arbitrary local variables, you'll have to add them to the email yourself in the exception handler.

Update: If you want to communicate variable values through a chain of exceptions, you'll have to insert them into the exception (i.e. in the message) when you catch it in the appropriate scope.

like image 36
Dan J Avatar answered Oct 02 '22 13:10

Dan J