One of the development challenges with SharePoint is setting up a generic error handler so that you can display a site-specific error page instead of the error pages displayed by SharePoint. Although SharePoint 2007 is built on top of ASP.NET 2.0/3.5, there are some facilities available in ASP.NET that don't work the same when run through SharePoint because of the way SharePoint handles most of the page-rendering events to facilitate loading dynamic content from the SharePoint database.

Typically in ASP.NET to implement an error handler you can implement a global.asax error handler and log the error and redirect to an error page. Global.asax events don't work the same way in SharePoint, and the error handler is not called. Instead what's needed is to implement a subclass of IHttpModule and then configure the web application to load it in response to errors.

To implement the error handler, first create the class ErrorHttpModule shown below. Provide your own implementation of the LogError and LogInfo methods to write to your chosen logger (I recommend log4net):

using System;
using System.Configuration;
using System.Web; 

namespace MikeKnowles.Cobalt
{
    /// <summary>
    /// Generic error handler for a .NET or SharePoint 2007 web application.
    /// </summary>
    public class ErrorHttpModule : IHttpModule
    {
        public void Init(HttpApplication app)
        {
            app.Error += new EventHandler(Application_Error);
        } 

        private void LogError(string message)
        {
            // TODO: write error message and stack trace of exception to your logger
        } 

        private void LogError(string message, Exception ex)
        {
            // TODO: write error message and stack trace of exception to your logger
        } 

        private void LogInfo(string message)
        {
            // TODO: write message to your logger. 
        } 

        public void Application_Error(object sender, EventArgs e)
        {
            Exception ex = HttpContext.Current.Server.GetLastError();
            string message = "HttpContext.Current.Request.Path=" + 
                HttpContext.Current.Request.Path + " "; 

            if (ex != null)
            {
                message += ex.Message;
                ex = ex.GetBaseException();
            }
            else
            {
                message += "HttpContext.Current.Server.GetLastError() is null";
            } 

            LogError(message, ex);
            String errorPagePath = 
                ConfigurationManager.AppSettings["GeneralErrorPath"];

            if (errorPagePath != null)
            {
                LogInfo("Transferring to " + errorPagePath);
                // transfer instead of redirect so the user still 
                // has requested page in address box
                HttpContext.Current.Server.Transfer(errorPagePath);
            }
            else
            {
                LogError("Property GeneralErrorPath not found in web.config.");
            }
        } 

        public void Dispose()
        {
        }
    }
}


Next, register the module with ASP.NET by adding the dll as the first item in the HttpModules section in Web.config. If the module is not listed first then error handling will not work as expected in SharePoint - you will still see the SharePoint generic handler in certain situations even though your error handler was executed. You will need to modify the 4 part name to match the dll you will include the code within (shown below on multiple lines for readability):

<add name="ErrorHttpModule" 
    type="Cobalt, Version=1.0.0.0, 
    Culture=neutral, 
    PublicKeyToken=2a75bd97c63f6363" />

Finally, add the following key to the AppSettings section of Web.config and provide the path to an error page within your web application. If you don't have one, just create a static html page. The property below points to a file in the SharePoint _layouts folder. The error page can reside anywhere you like as long as it's reachable by ASP.NET. Within a SharePoint application, I recommend making this a static file and not a page within the SharePoint database so the error page will be displayed in the event there are problems with the database or connecting to the database:

<add key="GeneralErrorPath" value="/_layouts/FOLDERNAME/GeneralError.aspx" />
Bookmark and Share  Comments [2] | Permalink | SharePoint
Friday, January 30, 2009 9:53:47 AM (Mountain Standard Time, UTC-07:00)
Couldn't you replace your while loop with ex = ex.GetBaseException()?
Saturday, February 14, 2009 1:15:50 PM (Mountain Standard Time, UTC-07:00)
Good call on replacing the while loop. I tested it out and it does in fact yield the same log messages. I've updated the code with your suggestion. Thanks!
Mike Knowles

Leave a Comment

Name (required)
Email (will not be published)
Website
 

Comment Preview
Subscribe
Top 5 Posts
Add Google Analytics to a SharePoint Publishing Site
Integrating jQuery 1.3, ASP.NET 3.5 Visual Studio 2008
Add Custom Table Formats to SharePoint Content Editor
Configuring log4net for SharePoint Windows Authentication
Convert Visual Studio 2008 Class Library Project to Web Application Project
Tags
ASP.NET (5) dasBlog (5) GoogleAnalytics (2) jQuery (1) log4net (2) SharePoint (18) WebDesign (3)
 
 
 
Spreadfirefox Affiliate Button
 
Download Notepad++