Mar 16 2010

Handling Unhandled Exceptions

Category: Events,Exception HandlingMike Lovell @ 7:34 pm

If an exception occurs outside a ‘try-catch block‘, it’s nice to have a way of either logging this, or having yourself notified.  The ‘EventLog‘ might be a way to go, but in the case of software running on your end-users PC, you might want to make it easy for them to send ‘unhandled exceptions‘ to you directly.  After all, if it’s complicated they may not have the technical expertise to get the information to you.  Something you might find easy might be beyond the reach of your end-users.

Here’s a quick example of both how to implement a ‘UnhandledException‘ EventHandler, and how to allow your end-user to easily email the information to you.

First lets make a little function that’s designed to fail!  This following function is going to always throw an Exception (divide by zero).

   1:  class Program
   2:  {
   3:      // Author Mike Lovell (mike.lovell@gotinker.com)
   4:   
   5:      private static int OtherFunction(int i)
   6:      {
   7:          var j = 0;
   8:   
   9:          return i / j;    // Divide by zero exception
  10:                          // will happen here
  11:      }
  12:   

Now the handler.  Inside ‘AppDomain.CurrentDomain‘ lives the ‘UnhandledException‘ event handler, this is fired when an exception is thrown (and of course, not handled!).  What we’re going to do is open up the end-users default mail client, with the ‘to‘, ‘subject‘ and ‘body‘ prefilled with the information we need.  In this case, we’re going to take the date, the full path and filename of the executable and the full exception (including stack trace).  Because we want the exception exactly as it would have appeared, and including any non-latin characters (their mail client may not support) we’ve Base64 encoded the UTF8 bytes of our exception string.

We can very easily reverse this process at the other end, to get to the exception.

  13:   
  14:      static void Main(string[] cargs)
  15:      {
  16:          AppDomain.CurrentDomain.UnhandledException += delegate(object sender, UnhandledExceptionEventArgs args)
  17:              {
  18:                  var exception = ((Exception)args.ExceptionObject);
  19:   
  20:                  var mailProcess = Process.Start
  21:                      (
  22:                          String.Format
  23:                              (
  24:                                  "mailto:null@gotinker.com?subject=Unhandled Exception ({0})&body={1}%0A{2}%0A%0A{3}",
  25:                                  HttpUtility.HtmlEncode(exception.Message),
  26:                                  DateTime.UtcNow.ToString("yyyy-MM-dd hh:mm:ss"),
  27:                                  Process.GetCurrentProcess().MainModule.FileName,
  28:                                  Convert.ToBase64String(Encoding.UTF8.GetBytes(exception.ToString())
  29:                              )
  30:                          )
  31:                      );
  32:              };

Now we want to call the function so we actually cause the exception to be thrown

  33:   
  34:          OtherFunction(123);
  35:      }
  36:  }

And the result?  Should look something like this:

GoTinker Exception Handler Email

Exception Handler Email

Download Visual Studio 2010 Project (6.78k)

Tags: , , , , , , ,