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.
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.
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());
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With