views:

509

answers:

6

If an exception propagates all the way up to the top of my application (which, of course, will never happen), I would like to offer the option of sending an error report to me before the program crashes. What I have in mind is wrapping everything in the Main function in a try-catch, and a little class that sends the stack trace and other information to my server. It sounds simple enough, but with something like this I am sure there are hurdles (such as security, future-proofing) that I haven't fully considered.

Is there an existing .NET library/project for this purpose? Or alternatively, does this sound like the right approach, simply catching all Exception in the application's entry point?

+2  A: 

You can use the Logging Application block from Enterprise Library to easily send emails when you catch and log exceptions. Here is some info on how to create a last chance exception handler. I've assumed you have a Winform application, but that's not clear by your question.

JP Alioto
+3  A: 

See this question on all the available logging frameworks in .NET, any of them should offer email notification.

I consider it a best practice to have a top level exception handler that collects and logs data on uncaught exceptions. As Meeh mentions in his comment to your question, you need one for each thread in your app.

There is an old article from Joel on the error reporting feature in FogBugz, maybe that will give you some more ideas. (I think I read it on his blog, but all I could find is this page form the FogBugz documentation).

Treb
A: 

Use the same tools that Windows uses: Windows Error Reporting (WER). It will do the crash analysis and bucketize your crashes so you can understand which are the most common. No code changes required, it works at the process level. It will log the failures from exceptions you can't catch.

All assuming you're running on Windows, of course.

Curt Nichols
Will WER send the error reports to the OP?
John Saunders
Not sure what OP means. WER sends the error reports to microsoft where they are stored. The developer can periodically retrieve them for analysis. The one requirement is that the developer registers with microsoft and provide a digital signature to identify his code at the cost of several hundreds of dollars. More here: http://en.wikipedia.org/wiki/Windows_Error_Reporting
urig
Original Poster.
Curt Nichols
+1  A: 

My standard disclaimer: I am a developer on this product.

Using a product (Runtime Intelligence) written by the company I work for (PreEmptive Soltutions) you can inject not only error reporting but also the ability to track when users are using your applications and what features they are using with minimal coding.

Using Dotfuscator to perform code injection (or IL weaving) we insert new code into your application binaries that sends usage data back to a server hosted at our facility (or optionally to any other arbitrary URL). If you send the data to us we provide you with a number of powerful analysis tools and reports on usage.

A basic version of this functionality is to be included in Visual Studio 2010 as well as access to a free data reporting portal (but with no SLA's, data retention guarantees or data privacy).

The ability to send arbitrary data back along with the usage information is limited to the commercial product, but you can contact PreEmptive Soltutions for a fully functional, free time limited evaluation version.

You can accomplish error reporting with the sample code below:

public partial class app : Application {
// field to temporarily store exception data        
    private Exception exp;
    void AppStartup(object sender, StartupEventArgs args) {
        // add a handler to catch any unhandled exceptions    
        this.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(ErrorHandler); 
        Window1 mainWindow = new Window1();
        mainWindow.ShowDialog();
    }

    // this will prompt the user if they want to report the exception
    void ErrorHandler(object sender, DispatcherUnhandledExceptionEventArgs e) {
        this.exp = e.Exception;
        if (MessageBox.Show("A " + exp.Message + " exception happened, should I report it?", "Error Occurrend", MessageBoxButton.YesNo) == MessageBoxResult.Yes) {
            ErrorHappened();
            e.Handled = true;
        }
    }

    // this method is called by the above ErrorHandler method and when run through Dotfuscator additional code will be injected into this method that will send a usage data message back to the server and the data in the dictionary (which will be exception data) returned by the ErrorData method will be included into the message and be stored and reported on the server
    [Feature("Exception", EventType = FeatureEventTypes.Tick, ExtendedKeySourceElement = SourceElements.Method, ExtendedKeySourceName = "ErrorData")]
    private void ErrorHappened() {
        // This is here as a placeholder for the exception feature attribute which will exit the application when executed
        AppShutdown(true);
    }

    // this method takes the exception data from the exp field and returns it as a dictionary of name/value pairs
    public Dictionary<string, string> ErrorData() {
        var retval = new Dictionary<string,string>();
        if (null != exp) {
            retval.Add("Error Message",exp.Message);
            retval.Add("Stack Trace",exp.StackTrace);
        }
        return retval;
    }
}
Joe Kuemerle
+1  A: 

I modified Jeff's User-Friendly Exception Handler and updated it for .NET 2.0/3.5, and I've had great luck with it. If an exception makes it all the way up the stack unhandled, a screenshot is taken and emailed along with a detailed stack trace to the dev team.

Chris Doggett
A: 

If you're working on an ASP.NET application you can also use the ASP.NET health monitoring features. Involves adding a few lines to the config file and you're off. http://msdn.microsoft.com/en-us/library/bb398933.aspx

Joshua S.