Good and bad exception (error) handling

by Heathesh 1. February 2010 02:36

I came across some code the other day and the person had implemented some shocking exception handling through out the application. Seeing this I thought I would touch on what I believe is good and bad practises when it comes to exception handling.

Good practises

1. Always handle errors, don't ever let an application fail and display an unhandled exception.

2. Always handle errors at the highest level possible. For example within a web application I personally add all my exception handling at either the event handler level (i.e. page_loads, button_click events) or I'll place a generic error handler in the global.asax file Application_Error event. For example:

    /// <summary>
    /// Handles any exceptions that occur in the application
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void Application_Error(object sender, EventArgs e)
    {
        //get the exception
        Exception ex = Server.GetLastError().GetBaseException();

        //log the error calling your own LogHandler class
        LogHandler.LogError(string.Format("{0}: {1}{2}{1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
            System.Environment.NewLine, ex.ToString()));

        //redirect to the error page to display the error message
        Response.Redirect(HttpUtility.HtmlEncode(string.Format("/Error.aspx?ErrorMessage={0}",
            ex.Message.Replace("\r", " ").Replace("\n", " "))));
    }


3. Always log errors, and ensure that error logging can be customized. In the above example I'm calling my LogHandler.LogError method. This method should have configurable values to indicate where to log the error to, be it email, text file, log file, event log, database where ever else possible.

4. Use try finally or "using" blocks to clean up objects, you don't have to use a catch statement:

In case you are specifically using the try because you want to execute a finally, you can either use a try finally without a catch or if the object you want to clean up implements iDisposable you can use a "using":

    //use try finally without a catch
    try
    {
        //do whatever
    }
    finally
    {
        //clean up objects
    }

    //use the "using" statement
    using (MyDisposableClass obj = new MyDisposableClass())
    {
        MyDisposableClass.DoWhatever()
    } //using will always dispose of the object, whether or not there is an exception


Bad practises

1. Using try catch uneccessarily, for example:

    //bad code 1:
    try
    {
        //do what ever
    }
    catch (Exception ex)
    {
        //unless you specifically want to do something with the exception,
        //you should not be doing this
        throw ex;
    }

    //bad code 2:
    try
    {
        //do what ever
    }
    catch
    {
        //unless you specifically want to do something with the exception,
        //you should not be doing this
        throw;
    }


2. Rethrowing an exception just to add your own message to it:

    //bad code
    try
    {
        //do what ever
    }
    catch (Exception ex)
    {
        //bad bad bad
        throw string.Format("There was an error: {0}", ex.Message);
    }


3. When dealing with an exception, you should not rethrow the variable or exception object:

This time we want to catch the exception and handle it by calling our "HandleException" method, but:

    //bad code
    try
    {
        //do what ever
    }
    catch (Exception ex)
    {
        HandleException(ex);
        //if we throw the "ex", we change the line number etc. in the stack
        //trace and the application thinks the error originated here, bad
        //for debugging
        throw ex;
    }

    //good code
    try
    {
        //do what ever
    }
    catch (Exception ex)
    {
        HandleException(ex);
        //by throwing the exception without specifying the "ex",
        //we will get the correct line etc. in the stack trace indicating
        //exactly where the error occurred
        throw;
    }

   
4. Throwing exceptions for validation errors. Just don't do it.

Final thoughts


1. When dealing with exceptions always remember that exceptions bubble up. This means that no matter how deep inside your application your exception happens, if you implement your exception handling at the highest level the exception will bubble up to the top.

2. Exceptions are resource intensive, where possible never purposely throw an exception, rather use boolean methods for validation etc. and return text messages that can be displayed to the user.

Happy coding!

Tags: , , , , ,

Development | .Net



Powered by BlogEngine.NET 1.5.0.7 (with enhancements by Heathesh)
Theme by Mads Kristensen (with tweeks by Heathesh)

Certifications

Microsoft Certified Professional

Microsoft Certified Technology Specialist

Answer Questions

 

Tag cloud

Calendar

<<  September 2017  >>
MoTuWeThFrSaSu
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

View posts in large calendar

http://heathesh.com