Click here to Skip to main content
15,885,914 members
Articles / General Programming / Exceptions
Article

Neater handling of exceptions

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
11 Oct 2013CPOL2 min read 4.5K   1  
ASP.net provides facilities in web.config for specifying error pages when an exception occurs, for example:            <customErrors

This articles was originally at wiki.asp.net but has now been given a new home on CodeProject. Editing rights for this article has been set at Bronze or above, so please go in and edit and update this article to keep it fresh and relevant.

ASP.net provides facilities in web.config for specifying error pages when an exception occurs, for example:

    <system.web>
        <customErrors mode="RemoteOnly" defaultRedirect="~/error-generic.aspx">
            <error statusCode="403" redirect="~/error-403.aspx" />
            <error statusCode="404" redirect="~/error-404.aspx" />
        </customErrors>
    </system.web>
 

This example redirects error 403 & 404 to specific pages, and all other errors to a generic page. This works great for the most part, but there are a couple of problems with it:

1. It doesn't allow for custom logging, and

2. Because of how the page is served, it returns with a HTTP status of 200 instead of 500 (or something useful).

However, both of these problems can be overcome fairly easily, using a custom HttpModule to handle your errors. First, create a new class:

public class ErrorModule : IHttpModule
{
    public void Dispose() { }

    public void Init(HttpApplication context)
    {
        context.Error += new EventHandler(Context_Error);
    }

    public void Context_Error(object sender, EventArgs e)
    {
        HttpApplication application = (HttpApplication)sender;
        HttpContext context = application.Context;
        System.Configuration.Configuration configuration = WebConfigurationManager.OpenWebConfiguration("~");
        SystemWebSectionGroup systemWeb = (SystemWebSectionGroup)configuration.GetSectionGroup("system.web");
        CustomErrorsSection customErrorsSection = systemWeb.CustomErrors;

        // If customerrors mode == off, then just let IIS handle it
        if (customErrorsSection.Mode != CustomErrorsMode.Off)
        {
            // If mode == on or its a remote request, we want to get the pretty page
            if (customErrorsSection.Mode == CustomErrorsMode.On || !context.Request.IsLocal)
            {
                Exception ex = context.Error;
                HttpException httpException = (HttpException)ex;

                string sURL = customErrorsSection.DefaultRedirect;
                if (httpException != null)
                {
                    context.Response.StatusCode = httpException.GetHttpCode();
                    CustomErrorCollection customErrorsCollection = customErrorsSection.Errors;
                    CustomError customError = customErrorsCollection[context.Response.StatusCode.ToString()];
                    if (customError != null)
                        sURL = customError.Redirect;

                    // Log the actual cause
                    ex = httpException.GetBaseException();
                }
                else
                {
                    context.Response.StatusCode = 500;
                }


/*

Put custom logging here!
*/

                context.ClearError();
                context.Server.Transfer(sURL);
            }
        }
    }
}
 

Then, in web.config, add the following:

    <system.web>
        <httpModules>
            <add name="ErrorModule" type="ErrorModule" />
        </httpModules>
    </system.web>
 

When ISS loads the application, it loads the ErrorModule class and execute it's Init() method, which adds a custom handler for the Application.Error event. The handler is where the magic happens.

First, it reads the customErrors section of web.config, so it can use your settings. Next it checks the error mode, so that when you don't want to bypass the default error page, it just returns without doing anything.

After setting the default error URL, it checks if the error is a HttpException, if so it sets the response HTTP status to the code returned by the exception, and checks the code against the any custom pages you've defined in the customErrors section. If it finds a match, it updates the URL with the one from web.config. If it is not a HttpException, it sets the HTTP status to 500 (Internal server error). At this point you can add custom error logging. It then clears the error, so IIS won't do it's thing, and redirects to the selected page.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
The ASP.NET Wiki was started by Scott Hanselman in February of 2008. The idea is that folks spend a lot of time trolling the blogs, googlinglive-searching for answers to common "How To" questions. There's piles of fantastic community-created and MSFT-created content out there, but if it's not found by a search engine and the right combination of keywords, it's often lost.

The ASP.NET Wiki articles moved to CodeProject in October 2013 and will live on, loved, protected and updated by the community.
This is a Collaborative Group

754 members

Comments and Discussions

 
-- There are no messages in this forum --