Click here to Skip to main content
Click here to Skip to main content

Handling Error Centrally in a SharePoint Application

By , 20 May 2008
 

Introduction

It is always nice if SharePoint also displays all types of error message in a friendly screen like other ASP.NET projects do. And it is possible in a very easy way. This sample code shows how to handle errors centrally in a SharePoint application. Well, this technique also applies for other ASP.NET projects. And, this is a better technique than handling errors in Global.aspx. I have also used the Logging Application Block of the Microsoft Enterprise Library to log errors in to a file.

Problem

Many SharePoint developers face a problem when they want to handle errors centrally. In any ASP.NET application, it is an easy task; we can simply handle errors from the Application_Error function in the Global.aspx file; But in SharePoint, it never reaches that function. I have seen other developers struggling to make it work in different ways; so I decided to take a different approach.

Solution

To solve the problem, I have implemented an IHttpModule interface and used the DLL in my project. An HTTP module is called on every request in response to the BeginRequest and EndRequest events. As a result, the module runs before and after a request is processed.

By using the IHttpModule, we can not only do error handling, but also lots of other things. If the ASP.NET application is running under IIS 6.0, we can use the HTTP modules to customize requests for resources that are serviced by ASP.NET. This includes ASP.NET Web pages (.aspx files), Web services (.asmx files), ASP.NET handlers (.ashx files), and any file type that we have mapped to ASP.NET. If the ASP.NET application is running under IIS 7.0, we can use HTTP modules to customize requests for resources that are served by the IIS. This includes not just ASP.NET resources, but HTML files (.htm or .html files), graphics files, and so on.

Understanding the Code

Let’s jump into the code. In the ErrorModule class, the Init function is called with the HttpApplication object. This object contains information about our application. We can do lots of useful things with this object. But for our problem, we only need to attach an event handler to the HttpApplication.Error event.

Context.Error += new EventHandler(Application_Error);

Now, we will do the main coding in the Application_Error function:

public void Application_Error(object sender, EventArgs e)
{            
   HttpContext Context = HttpContext.Current;
   Exception exception;
   for (exception = Context.Server.GetLastError(); 
        exception.InnerException != null; 
        exception = exception.InnerException) { }

   String code = DateTime.Now.ToString("ddMMyyyy-HHmmfff");
   String Message = exception.Message + Environment.NewLine + 
                    "Stack Trace: " + exception.StackTrace;

   Logger.Write(Message, "General",5, 1, 
                System.Diagnostics.TraceEventType.Critical, code);  
        
   HttpContext.Current.Application.Add("ErrorCode", code);
   HttpContext.Current.Application.Add("LastException", exception);

   String CustomErrorPagePath = 
     System.Configuration.ConfigurationManager.AppSettings["CustomErrorPagePath"];

   ((System.Web.HttpApplication)(sender)).Response.Redirect(CustomErrorPagePath);
}

In this function, we have to first take the instance of HttpContext. From this object, we can get the exception information. And we will then get the last exception object. We now loop through that exception object to go down in depth and find the first error that raised the exception.

for (exception = Context.Server.GetLastError(); 
     exception.InnerException != null; 
     exception = exception.InnerException) { }

Next, we generate an error code. This is for a reference that the application user will see in their error page and which they can use to call the support team with. The support team can search the log file with the error code, and can determine what actually caused the error by looking at the stack trace.

Here, I am creating the error message with the error info and the stack trace. And the following code tells the Microsoft Enterprise Library’s Logging Application Block to log the error:

Logger.Write(Message, "General",5, 1, 
       System.Diagnostics.TraceEventType.Critical, code);

We can also configure whether we want to keep the log in a database, or in a flat file, or in other places. Now, we need to save the error so that we can show it in a custom error page. The following code saves the error code and the exception object in the HttpApplicationState:

HttpContext.Current.Application.Add("ErrorCode", code);
HttpContext.Current.Application.Add("LastException", exception);

Now, we have to redirect to the custom error page. For this, we first read the URL from the configuration file and redirect to that page.

String customErrorPage = 
  System.Configuration.ConfigurationManager.AppSettings["CustomErrorPage"];
((System.Web.HttpApplication)(sender)).Response.Redirect(customErrorPage);

From the custom error page, first we have to get the exception object and the error code that we have saved.

Exception ex = (Exception)HttpContext.Current.Application.Get("LastException");
String Code = (string)HttpContext.Current.Application.Get("ErrorCode");

And then, we need to show the error message in a label or some another control in a nice way.

Configuration & Deployment

After compiling the project, we need to put the CentralErrorHandler.dll to the GAC, either by using gacutil or just by dragging the DLL to the folder C:\WINDOWS\assembly.

And to enable the application to use our newly created ErrorModule, we need to update the web.config file of our SharePoint application and put the following lines:

<system.web>
   <httpModules>
     <add name="MyErrorHandler" type="CentralErrorHandler.ErrorModule, 
                                      CentralErrorHandler, Version=1.0.0.0, 
                                      Culture=neutral, PublicKeyToken=06a3e095a0c5fc38 " />
   </httpModules>
</system.web>

We also need to add the CustomErrorPagePath to redirect to our custom error page.

<appSettings>
   <add key="CustomErrorPagePath" value="http://MySharePointSite/MyErrorHandler.aspx" />
</appSettings>

As I said earlier, we can also configure where we want to log the error message, and what the format of our error logging should be. The following configuration is for writing the error in a file:

<configuration>
  
  <configSections>
    <section name="loggingConfiguration" 
       type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, 
             Microsoft.Practices.EnterpriseLibrary.Logging, Version=3.1.0.0, 
             Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
  </configSections>

  <loggingConfiguration name="Logging Application Block" tracingEnabled="true" 
            defaultCategory="General" logWarningsWhenNoCategoriesMatch="true">
    <listeners>
      <add fileName="C:\trace.log" header="----------------------------------------" 
           footer="----------------------------------------" 
           formatter="Text Formatter" 
           listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.
                             FlatFileTraceListenerData, 
                             Microsoft.Practices.EnterpriseLibrary.Logging, 
                             Version=3.1.0.0, Culture=neutral, 
                             PublicKeyToken=b03f5f7f11d50a3a" 
           traceOutputOptions="None"
           type="Microsoft.Practices.EnterpriseLibrary.
                 Logging.TraceListeners.FlatFileTraceListener, 
                 Microsoft.Practices.EnterpriseLibrary.Logging, Version=3.1.0.0, 
                 Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 
           name="FlatFile TraceListener" />
   ..................
   ..................
  </loggingConfiguration>

</configuration>

For more information about formatting error messages and configuring the destination of the Logging Application Block, please take help from MSDN. We also need to put the MyErrorHandler.aspx and MyErrorHandler.aspx.cs files to a SharePoint site virtual path (e.g., C:\Inetpub\wwwroot\wss\ MySharePointSite).

References

To know more about the Logging Application Block, IHttpModule, and HttpApplication, you can go through the following links.

License

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

About the Author

Anupam Ranku
Software Developer (Senior) Gen-i, Australia
Australia Australia
Member
Expertise area: ASP.NET, C#, Microsoft Office SharePoint 2010 & 2007, Web Service, Windows-based Applications etc.
 
Blog: http://mydevdiary.blogspot.com/

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Questioncannot redirect and cannot handle error 404 page not foundmemberLaith Al-Momani23 Apr '13 - 13:27 
thank you for your post i tried to use it since along last time but it didn't work with.
i am trying today to use it in both SharePoint 2010 and 2007, at the beginning i want your help for 2010 please.
the first issue is that the redirect not working it's still show me yellow page with below message, but my config file under 80 folder which is my web application port doesn't have below information that's appear in yellow error page, my config file what have inside is not as appear below.
 
---------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------
 
Server Error in '/' Application.
Runtime Error
 
Description: An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed.
 
Details: To enable the details of this specific error message to be viewable on the local server machine, please create a tag within a "web.config" configuration file located in the root directory of the current web application. This tag should then have its "mode" attribute set to "RemoteOnly". To enable the details to be viewable on remote machines, please set "mode" to "Off".
 

<!-- Web.Config Configuration File -->
 





 
Notes: The current error page you are seeing can be replaced by a custom error page by modifying the "defaultRedirect" attribute of the application's configuration tag to point to a custom error page URL.
 

<!-- Web.Config Configuration File -->
 





 
---------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------
 

the Second issue what if want to handle errors of 404 "page not found" ...etc,when i type wrong url the code in ErrorModule not fired or accessed, i don't want to handle from web.config , i want to handle it from ErrorModule class as center point to handle all errors.
 
Thanks for you support your effort is highly appreciated.
GeneralCustom Error Message Display Incorrect Problemmembersams198576 Mar '11 - 15:24 
Hi,
 
Thanks so much for this useful post.
 
I have tried the same way as per download source to get the Error Message and Error Code to display,
 
however the error message sometimes does not display correctly after enter the same invalid url.
 
e.g: F5 refresh display custom error message, sometimes display "Object reference not set to an instance of an object"
 
I suspect something wrong in if (HttpContext.Current.Application.Get("LastException") != null)
 
any idea? appreciate your advices, thank you.
AnswerRe: Custom Error Message Display Incorrect ProblemmemberAnupam Ranku6 Mar '11 - 15:41 
I presume when you are refreshing page (by hitting F5) the HttpContext.Current.Application collection is getting empty. So the key "LastException" no longer exists in the collection.
 
If you need to refresh the page, save the exception data to somewhere else (ViewState, Session etc), in first page load.
 
Hope this will help. Thanks!
GeneralRe: Custom Error Message Display Incorrect Problemmembersams198576 Mar '11 - 15:50 
Agree, let say I want to save the exception data in ViewState,
 
is it add to ViewState after HttpContext.Current.Application.Add("LastException", exception);
 
can you provide me a sample on how to add the exception data into ViewState?
 
Thanks
GeneralRe: Custom Error Message Display Incorrect Problem [modified]membersams198576 Mar '11 - 15:57 
besides, when hitting a same error, the error message is inconsistent , sometimes it show on the custom error message "Does not contain any information about error!!!" and sometime show the actual error (let say "No item exists at http...."), could it be caused by the network or hardware (e.g load balancer)? any suggestion on solving it? thanks.
modified on Sunday, March 6, 2011 10:10 PM

AnswerRe: Custom Error Message Display Incorrect ProblemmemberAnupam Ranku6 Mar '11 - 16:45 
The code relies on the exception object returned from HttpContext.Current.Server.GetLastError();
 
You can set a breakpoint on that function. Here are the codes. And try to find the error.
 
HttpContext Context = HttpContext.Current;
Exception exception;
for (exception = Context.Server.GetLastError(); exception.InnerException != null; exception = exception.InnerException) { }
GeneralRe: Custom Error Message Display Incorrect Problem [modified]membersams198576 Mar '11 - 19:15 
could it be the codes (as per download source) problem if I only hit the bug on production environment (got load balancer), while the development environment(without load balancer) is work perfectly? thanks
modified on Monday, March 7, 2011 8:14 PM

GeneralRedirect to Custom Error pagememberafzalu2 Feb '11 - 6:30 
Hi,
 
Thanks for the useful post, helps me.
 
Though, its been an old post, but in my scenario It still works for me.
 
I'm able to log in custom error file, but the last line of Code where we redirect to Custom error page seems to me not working.
 
I have a simple application page (Sharepoint 2010) where I throw a simple Exception, and I got that in my Custom class but I didn't get
redirected.
 
Please advise me in this regard.
 
Thanks.
GeneralRe: Redirect to Custom Error pagememberAnupam Ranku21 Feb '11 - 11:51 
Hi,
Sorry for the late reply. Have you managed to solve the problem?
 
I cannot tell you the exact solution until I see your code.
 
However you can try doing "Response.Redirect(customErrorPage, true);"
 
Regards,
Ranku
GeneralRe: Redirect to Custom Error pagememberMember 268341121 Apr '11 - 20:53 
Thanks for your article.
 
Do you now or this solution works with SP2010. I’m having the same problem. When I debug the solution the Application_Error code is running, error are written in the log, but the redirect does not work. I’m getting the standard error page. It seems that the error isn’t cleared because in the system logs there is an unhandled error exception.
 

Server Error in '/' Application.
--------------------------------------------------------------------------------
 
Runtime Error
Description: An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed remotely (for security reasons). It could, however, be viewed by browsers running on the local server machine.
 
Details: To enable the details of this specific error message to be viewable on remote machines, please create a tag within a "web.config" configuration file located in the root directory of the current web application. This tag should then have its "mode" attribute set to "Off".
 

<!-- Web.Config Configuration File -->
 






 
Notes: The current error page you are seeing can be replaced by a custom error page by modifying the "defaultRedirect" attribute of the application's configuration tag to point to a custom error page URL.
 

<!-- Web.Config Configuration File -->
 





GeneralRe: Redirect to Custom Error pagememberRob Canters21 Apr '11 - 21:06 
Found it,
 
In SP2010 use SPUtility.TransferToErrorPage to redirect to error page.
QuestionTrouble setting up the Error Handling HttpModulememberMember 24744197 Nov '10 - 23:34 
Hei there,
 
Great article!
 
I'm trying to set this centralized error handler up on my server. As an administrator, I managed to get redirected to the custom error page. Great!
 
However, when I tried to log in as a normal user to the SharePoint application, I am seeing the SharePoint default error page. Is there anything that I have missed out?
 
I installed SharePoint 2010 on the server. In my web.config, my since it is an IIS 7 application, I have to add my CustomError module to <Modules> within the <system.webServer> node, instead of <HttpModules> of the <system.webgt; node. It did not work, so I tried on both <httpModules> and <Modules>, but to no avail. I have made sure my callStack is set to true, too.
 
Please help! Thanks.
GeneralI cannot Handling Error Centrally in a SharePoint Application according to instructions provided. [modified]memberLaith Al-Momani7 Nov '10 - 2:13 
Dear Anupam,
Kindly note that i tried to follow article that you post, it's working properly for ASP.net application but when i tried to apply it to my SharePoint site it's not working, i don't know the reason since i putting in the consideration the steps you provided in the Configuration Deployment section,Please help me out.
 
Best Regards,
modified on Sunday, November 7, 2010 10:58 AM

AnswerRe: I cannot Handling Error Centrally in a SharePoint Application according to instructions provided.memberAnupam Ranku7 Nov '10 - 11:29 
Hi Laith,
 
Can you please check that you have added the following line in sharepoint web.config file?

 
And make sure you don't have any tag in (after adding the previous MyErrorHandler element)
 
Best regards,
GeneralTypeInitializationExceptionmemberRyan Henson3 Nov '09 - 5:30 
Thank you for this great article. I have been trying to replicate what you have accomplished here in my own environment but have run into some snags along the way. I've ended up making some of my own modifications but I don't believe they are at fault as the exception is the same even when I comment out the contents of my methods. I believe this is a configuration issue but I can't seem to figure out where exactly. Thoughts?
 
CustomErrorHandler
public class CustomErrorModule : IHttpModule
    {
        private static readonly ILog Log;
 
        static CustomErrorModule()
        {
            try
            {
                Log = LogManager.GetLogger(typeof(CustomErrorModule));
            }
            catch
            {
            }
        }
 
        #region IHttpModule Members
 
        void IHttpModule.Dispose()
        {
            //throw new Exception("The method or operation is not implemented.");
        }
 
        void IHttpModule.Init(HttpApplication Context)
        {
            Context.Error += new EventHandler(Application_Error);
            log4net.Config.XmlConfigurator.Configure();
        }
 
        #endregion
 

        public void Application_Error(object sender, EventArgs e)
        {
            HttpContext Context = HttpContext.Current;
 
            // Log the Exception
            Exception exception;
            for (exception = Context.Server.GetLastError(); exception.InnerException != null; exception = exception.InnerException) { }
            String code = DateTime.UtcNow.ToString("ddMMyyyy-HHmmfff");
            //Log.Error(code + ": " + exception.Message, exception);
            HttpContext.Current.Application.Add("ErrorCode", code);
            HttpContext.Current.Application.Add("LastException", exception);
 
            // Look for an Error Handler for the excepting application
            ErrorHandlerConfiguration config = ErrorHandlerConfiguration.GetConfig();
            ErrorHandlerBase handler = config.GetElementTypeByKey(Context.Request.Path);
            if (handler != null)
                handler.HandleError(Context);
 
            // Redirect to the generic error page
            string CustomErrorPagePath = System.Configuration.ConfigurationManager.AppSettings["CustomErrorPagePath"];
 
            ((System.Web.HttpApplication)(sender)).Response.Redirect(CustomErrorPagePath);
        }
    }
 
Exception
Event Type:	Warning
Event Source:	ASP.NET 2.0.50727.0
Event Category:	Web Event 
Event ID:	1309
Date:		11/3/2009
Time:		11:18:42 AM
User:		N/A
Computer:	**********
Description:
Event code: 3005 
Event message: An unhandled exception has occurred. 
Event time: 11/3/2009 11:18:42 AM 
Event time (UTC): 11/3/2009 4:18:42 PM 
Event ID: e814b5d888554c81b8c7ed6578ccc5c4 
Event sequence: 2 
Event occurrence: 1 
Event detail code: 0 
 
Application information: 
    Application domain: /LM/W3SVC/1576347596/Root/_layouts/images-2-129017387220526596 
    Trust level: Full 
    Application Virtual Path: /_layouts/images 
    Application Path: C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\template\images\ 
    Machine name: ******* 
 
Process information: 
    Process ID: 2012 
    Process name: w3wp.exe 
    Account name: NT AUTHORITY\NETWORK SERVICE 
 
Exception information: 
    Exception type: TypeInitializationException 
    Exception message: The type initializer for '*******.HttpModules.CustomErrorModule' threw an exception. 
 
Request information: 
    Request URL: http://******/_layouts/images/menudark.gif 
    Request path: /_layouts/images/menudark.gif 
    User host address: ********* 
    User:  
    Is authenticated: False 
    Authentication Type:  
    Thread account name: NT AUTHORITY\NETWORK SERVICE 
 
Thread information: 
    Thread ID: 9 
    Thread account name: NT AUTHORITY\NETWORK SERVICE 
    Is impersonating: False 
    Stack trace: 

GeneralRe: TypeInitializationExceptionmemberAnupam Ranku3 Nov '09 - 5:47 
Can you please omit this section and try again?
 
private static readonly ILog Log;
 
static CustomErrorModule()
{
try
{
Log = LogManager.GetLogger(typeof(CustomErrorModule));
}
catch
{
}
}
GeneralTypeInitializationExceptionmemberRyan Henson3 Nov '09 - 5:25 
Thank you for this great article. I have been trying to replicate what you have accomplished here in my own environment but have run into some snags along the way.
 
CustomErrorHandler
public class CustomErrorModule : IHttpModule
{
private static readonly ILog Log;
 
static CustomErrorModule()
{
try
{
Log = LogManager.GetLogger(typeof(CustomErrorModule));
}
catch
{
}
}
 
#region IHttpModule Members
 
void IHttpModule.Dispose()
{
//throw new Exception("The method or operation is not implemented.");
}
 
void IHttpModule.Init(HttpApplication Context)
{
Context.Error += new EventHandler(Application_Error);
log4net.Config.XmlConfigurator.Configure();
}
 
#endregion
 

public void Application_Error(object sender, EventArgs e)
{
HttpContext Context = HttpContext.Current;
 
// Log the Exception
Exception exception;
for (exception = Context.Server.GetLastError(); exception.InnerException != null; exception = exception.InnerException) { }
String code = DateTime.UtcNow.ToString("ddMMyyyy-HHmmfff");
//Log.Error(code + ": " + exception.Message, exception);
HttpContext.Current.Application.Add("ErrorCode", code);
HttpContext.Current.Application.Add("LastException", exception);
 
// Look for an Error Handler for the excepting application
ErrorHandlerConfiguration config = ErrorHandlerConfiguration.GetConfig();
ErrorHandlerBase handler = config.GetElementTypeByKey(Context.Request.Path);
if (handler != null)
handler.HandleError(Context);
 
// Redirect to the generic error page
string CustomErrorPagePath = System.Configuration.ConfigurationManager.AppSettings["CustomErrorPagePath"];
 
((System.Web.HttpApplication)(sender)).Response.Redirect(CustomErrorPagePath);
}
}
GeneralTypeInitializationExceptionmemberRyan Henson3 Nov '09 - 5:25 
Thank you for this great article. I have been trying to replicate what you have accomplished here in my own environment but have run into some snags along the way.
 
CustomErrorHandler

GeneralException/Error Handling....memberidltsa22 Aug '08 - 3:36 
Nice Post!
 
My two cents..
 
If the HTTPModule has to access the StackTrace it still needs to be provided by SharePoint.
 
Unless the CallStack attribute in SafeMode tag is set to true, the HTTPModule will not be able to print the exception and getLastError will always return true.
 

Pls refer: http://www.graphicalwonder.com/?p=648[^]
GeneralRe: Exception/Error Handling....memberAnupam Ranku22 Aug '08 - 7:12 
Thanks Smile | :)
 
Actually, from the beginning of SharePoint 2007 development, we had to set the CallStack to true otherwise we wont get any details error message. I thought every SharePoint developer knows it; otherwise, they are living in hell. Smile | :)
 
But I agree, it is a valuable and helpful information to share.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130523.1 | Last Updated 20 May 2008
Article Copyright 2008 by Anupam Ranku
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid