views:

296

answers:

4

I am developing a winforms application and I would like to know what are the best practices for exception handling. Whenever there is an exception occurring I open an exception dialog displaying the necessary information i.e. the message and stacktrace. Major confusion that I have is in cases where I want the user to see only a friendly message but at the same time make sure that the developer would get the necessary data for debugging. What is the best way to do this?

+1  A: 

I haven't used it personally, but Red Gate's Exception Hunter looks like a pretty cool tool. Your best bet might be to log the error to disk so it's available should someone need to look at it, but not popping up in the way of your users. If you want, you could open a window asking the user to submit the exception information and stack trace to you through your web site (by just clicking OK). Avoid sending private information, which probably means not sending parameter values.

Edit: Oh, avoid saying "Exception and stack trace." Say "An error has occurred, but with your help we can fix it faster. Would you like to automatically send the error information to ____ at this time? Please note that no personal information will be transmitted with the error report. You may click 'Details' to show the full information of the report." If they click details, vertically expand the window to show a read only textbox with the data.

280Z28
A: 
catch (Exception ex)
{
    cApp.DB.LogException(ex);
    Messagebox.Show(...);
}

The cApp.DB.LogException(ex) logs to a database table, unless the database is down then it adds it to a text file.

JBrooks
A: 

I have a utility method I use in utility programs I write in WinForms. With a little care, it might be useful in Production WinForms applications (let the experts not spare their criticisms):

Convenience overloads:

private void PerformUIAction(Action action)
{
    PerformUIAction(action, (string) null);
}

private void PerformUIAction(Action action, string message)
{
    PerformUIAction(action, () => message);
}

The real one:

private void PerformUIAction(Action action, Func<string> messageHandler)
{
    var saveCursor = Cursor;
    Cursor = Cursors.WaitCursor;
    try
    {
        action();
    }
    catch (Exception ex)
    {
        MessageBox.Show(
            messageHandler() ?? ex.Message,
            "Exception!",
            MessageBoxButtons.OK,
            MessageBoxIcon.Error,
            MessageBoxDefaultButton.Button1,
            MessageBoxOptions.DefaultDesktopOnly);
        // Replace with logging code. The important part is ex.ToString(),
        // not ex.Message
        Debug.WriteLine(ex.ToString(), "Exception");
        throw;
    }
    finally
    {
        Cursor = saveCursor;
    }
}

Example of use:

private void _samplesMenu_AfterSelect(object sender, TreeViewEventArgs e)
{
    PerformUIAction(
        delegate
            {
                // Do the real work of the event in here.
                // You can reference sender and e
            },
        delegate
            {
                return string.Format(
                    "Error while processing action {1} for node {0}", 
                    e.Node.FullPath, e.Action);
            });
}
John Saunders
A: 

Thanks for your answers... I guess dumping the stack in some log file and showing user only friendly message would work in my case :)

SA