Windows Phone From Scratch
Jon Galloway and I have been working together on The Full Stack project. This week, we’ve been banging our heads together trying to figure out why our Windows Phone application crashes on testing when submitted to the Marketplace, yet it tests fine on my PC and on my phone.
We finally decided that we needed some debugging information from when it crashes and that the best way to do that would be to catch the exception that we are presuming is being thrown, and get a stack trace. But how to get that to us?
Catching the exception and showing it locally wasn’t a terribly hard problem to solve. In App.xaml.cs there is a method Application_UnhandledException. We opted to create an error message based on the exception and first display it in a message box.
The first hurdle is that the argument to Application_UnhandledException is not the exception, but rather is an ApplicationUnahandledExceptionEventArg. You can get to the exception, however, through its ExceptionObject property.
The second hurdle was that we couldn’t open a MessageBox because we were on the wrong thread, and you can’t just call Dispatcher.BeginInvoke because you are not in a view. Fortunately, you can call Deployment.Current.Dispatcher.BeginInvoke, which is what we did,
Deployment.Current.Dispatcher.BeginInvoke( () => { string errorMsg = string.Format( "Exception caught. Message: {0} \r\nTrace: {1}", e.ExceptionObject.Message, e.ExceptionObject.StackTrace ); System.Windows.MessageBox.Show( errorMsg ); SendEmailOfException( errorMsg ); } );
This shows the error and the stack trace in a MessageBox, but that is of limited utility when the error is happening at the tester’s location and not our own. Thus, we added the call to our method SendEmailOfException.
The method SendEmailOfException uses the Email launcher to pass the error message (and stack trace) to the email application, pre-filling in the To field and the Subject field as well. All that is needed is an instance of EmailComposeTask. We invoke the actual dispatch to email by calling Show(),
private static void SendEmailOfException(string msg) { var emailComposeTask = new EmailComposeTask { To = "jliberty@microsoft.com; jon.galloway@microsoft.com", Subject = "Who Is That Error", Body = msg }; emailComposeTask.Show(); }
It’s great. We put in an exception to test and as soon as the exception was raised the MessageBox opens. Close the MessageBox and the exception appears in the outbound Email. Send it and we instantly received the email in our inbox:
From: Jesse Liberty Sent: Tuesday, April 26, 2011 5:50 PM To: Jesse Liberty; Jon Galloway Subject: Who Is That Error Exception caught. Message: Exception thrown in
loginSucceeded method! Trace: at WhoIsThatWinPhone.View.Authentication.<loginSucceeded>b__0(Object o, FacebookApiEventArgs e) at Facebook.FacebookClient.OnGetCompleted(FacebookApiEventArgs args) at Facebook.FacebookClient.DownloadDataCompleted(Object sender, DownloadDataCompletedEventArgsWrapper e) at Facebook.FacebookClient.<>c__DisplayClass7.<ApiAsync>b__2(String json, Exception ex) at Facebook.FacebookClient.ResponseCallback(IAsyncResult asyncResult, Action`2 callback, Object state) at Facebook.FacebookClient.<>c__DisplayClass7.<ApiAsync>b__4(IAsyncResult ar) at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClassa.<InvokeGetResponseCallback>b__8(Object state2) at System.Threading.ThreadPool.WorkItem.doWork(Object o) at System.Threading.Timer.ring()
Note: Jon is writing this up for his blog as well. Be sure to check it out.
8 Responses to Email a stack trace when things blow up in Windows Phone