Catching unhandled exceptions in SharePoint


If you have done some dev stuff with MOSS you have most likely seen this:

UnexpectedError

An unexpected error has occurred. ” is something that you probably don’t want to see at your browser…. you want to have customized error page. In ASP.NET application you normally put Application_Error into you global.asax file. However in SharePoint that place has been taken by the product itself 🙂 So if you want to do customized approach then you can take HttpModule approach which I’m going to go through in this post.

So let’s create our custom exception handler http module. Here’s the code for that:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System;
using System.Web;

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

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

  void context_Error(object sender, EventArgs e)
  {
    Exception[] unhandledExceptions = HttpContext.Current.AllErrors;

    foreach (Exception ex in unhandledExceptions)
    {
      // TODO: log your errors
    }

    HttpContext.Current.Server.ClearError();
    HttpContext.Current.Response.Clear();
    HttpContext.Current.Server.Transfer("/_layouts/MyCustomErrorPage.aspx");
  }
}

You can probably see from the code that I’ll attach my code to the Error event and in my event I’ll do some basic stuff and then transfer to my MyCustomErrorPage.aspx. I used Server.Transfer just because I want user to stay at the same url where exception happened. If I would use Response.Redirect it would “change” the url at the users browser. Same “change” would happen if your custom error page would be normal SharePoint publishing page (i.e. /Pages/MyCustomErrorPage.aspx). If the url stays the same the user can actually press F5 and retry the operation right away. Of course it can be bad thing too and you may want to redirect to another page to avoid creating the same exception all over again. I’ll let you decide what you want 🙂 So do some testing and then decide what’s good for you.

But one important thing to notice. You need to put your IHttpModule before SharePoint specific modules in your web.config or otherwise your error routines may not work as you would expect. Here’s example from that:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<configuration>
 <!-- ... -->
  <httpModules>
   <clear />
   <add name="MyExceptionHandler" type="MyExceptionHandler,Example, 
      Version=1.0.0.0, Culture=neutral,PublicKeyToken=34a2bd01f6f6eb10" />
   <add name="SPRequest" type="Microsoft.SharePoint.ApplicationRuntime.SPRequestModule, 
      Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
   <add name="OutputCache" type="System.Web.Caching.OutputCacheModule" />
   <!-- ... -->

  </configuration

See line 6 where I put my exception handler definition.

Anyways… Happy hacking!

J

Comments (21)

  1. Hacía tiempo que no revisaba mis RSS sobre SharePoint , y claro me ha costado ponerme al día, y aquí

  2. gangadhar says:

    I am getting error saying that The given assembly name or codebase was invalid.

  3. Ram says:

    Janne,

             We tried the same appraoch by creating a HTTPmodule hooking to Error event  and registered the same as a first module in MOSS web.config.But it did not work for us !

         Do you have any idea that what may be the cause of the issue ?

    Regards,

    Ram

  4. Hi Ram!

    Are you able to debug your code? I mean that if you attach your VS to the w3wp.exe process you’re able to step through the lines of you handler?

    J

  5. Asad kamran says:

    Janee,

    But when i deployed the http module i get this error:

    The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047

    Line 146:      <add name="MyExceptionHandler" type="MyExceptionHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=229eff298acf7a7d" />

  6. ed says:

    Thank f for that.  1st person suggesting a solution.  My inferior but workable solution was to remove the error.aspx page from the layouts folder – the application_error event then fires in global.asax and I was able to handle it there.

  7. ed says:

    Just wondering, can something similar be done for unauthorised access errors?

  8. Brent says:

    Will your saolution work when the message is

    File not found?

  9. Naman says:

    I created the httpmodule and added the tag in Web.config.

    <httpModules>

         <clear />

         <add name="SABICCustomError" type="SABICCustomError,SABICCustomError, Version=1.0.0.0, Culture=neutral, PublicKeyToken= 80a3837ac70f49e8" />

    Attaching debugger and putting a breakpoint doesnt works.

    Looking forward for any help.

    namanc@gmail.com

  10. m3rd says:

    what can you do if you limit a survey to only one response and the user gets an error page instead of a friendly "sorry, you cannot take the survey more than once." and then return them to the home page.

  11. Andy Burns says:

    Neat! I like that.

    One question though – what if I just want to use the HTTPModule to change the master page my error master page uses, rather than the simple.master it normally uses? I don’t seem to be able to do that.

    Or, come to that, of redirecting the error pages for a single site/url?  Hmm. Tricky.

    m3rd, I suppose you could use what Janne has built above, but look at the error and if it is the survey exception, cancel the error and redirect to your own page with that message.

  12. Ricardo Casquete says:

    Nice and Elegant….

    I was using before this approach which i think is worse than the one proposed by Janne

               AppDomain.CurrentDomain.UnhandledException  += new UnhandledExceptionEventHandler ( OnUnhandledException );

           private void OnUnhandledException ( object sender, UnhandledExceptionEventArgs e )

           {

               Logger.Log ( e.ExceptionObject.ToString ( ), CATEGORY_UNHANDLED_EXCEPTIONS );

           }

  13. drew says:

    I’m having trouble  implementing this.  I’m using it in conjunction with stsdev. The error never gets attached. Am I missing something? Any ideas/tips to get started?

  14. Steve B says:

    This was a nice insight into Error Handling in SharePoint and very useful.  I’ve implemented more-or-less your design with a few additional logical paths to decide how to handle errors based on the web.config file settings.  We also had a requirement to log any exceptions so we opted for the EventLog (which needed to be called by an elevated method call using SPSecurity) which again works perfectly.

    We’ve had a couple of Publishing-based projects recently that have certainly benefited from this so many thanks again. 😉

  15. Farrukh says:

    Hi, I have check this approach and it works fine for me. My custom page uses simple.master (just like error.aspx). I just need to ask if there would be any way to replace simple.master with my custom.master page.

  16. Faarukh says:

    Hi,

    I am able to create my on Custom Error Page with this approach, but some time it is throwing error in HTTPModule on Server.Transfer Statement. The error description is ""Error executing child request for ___.aspx". Can any body tell me regarding that. What workaround do i have to do for that. Note down that I implement this for my Custom Sharepoint (MOSS) Site.

  17. srinivas says:

    To fix Given assembly or code base name is invalid error,

    Go to SharePoint site Web.Config file

    Add the newly created modules like below

    <add name="Class Name" type="NameSpace.ClassName,NameSpace, Version=1.0.0.0, Culture=neutral,PublicKeyToken=Token" />

    please make sure that replace classname,namespace and token value according to your project

  18. Altaf says:

    That's lengthy solution. Try following one.

    go to web.config file.

    1)      Find out the following entry

    <SafeMode MaxControls=“200“ CallStack=“false“ DirectFileDependencies=“10“ TotalFileDependencies=“50“ AllowPageLevelTrace=“false“>

    And make following changes to it

    <SafeMode MaxControls=“200“ CallStack=“true“ DirectFileDependencies=“10“ TotalFileDependencies=“50“ AllowPageLevelTrace=“true“>

    2)      And

    <customErrors mode=“On“ />

    To

    <customErrors mode=“Off“ />

    That's it… Simple !

  19. Sampath says:

    I have implemented custom error handling mechanism in the similar way (Using Http Module).

    But when I browse for this page  http://<SiteURL>/_layouts/addcontentsource.aspx , I still get the sharepoint error page with the following error message:

    "This page is accessible only from a Shared Services Provider admin site."

    What could be the issue here ?

Skip to main content