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

Error Handling in ASP.NET

By , 5 Jun 2005
 

Sample Image - ErrorHandling.gif

Introduction

When errors occur in an ASP.NET application, they either get handled or propagates unhandled to higher scopes. When an unhandled exception propagates, the user may be redirected to an error page using different ASP.NET configuration settings. However, such a redirection may be prevented in the first place by handling the exceptions that get thrown. Error handling in ASP.NET therefore, may be divided into two separate logics:

  • Redirecting the user to an error page when errors go unhandled.
  • Handling exceptions when they get thrown.

Redirecting the user to an error page

There are two different scopes where we could specify which page the user should be redirected to, when errors go unhandled:

  • Page level (applies to errors that happen within a single page).
  • Application level (applies to errors that happen anywhere in the application).

Page Level

Use the errorPage attribute in the webform.

This attribute defines the page the user should be redirected to when an unhandled exception occurs in that specific page. For example,

<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" 
    AutoEventWireup="false" Inherits="WebTest.WebForm1" 
    errorPage="/WebTest/ErrorPages/PageError.html"%>

The errorPage attribute maps to the Page.ErrorPage property, and hence may be set programmatically. The value may optionally include query string parameters. If no parameters are added, ASP.NET would automatically add one with the name aspxerrorpath. This parameter would hold the value of the relative URL to this page, so that the error page would be able to determine which page caused the error.

If a value is specified in this attribute (or property) and an unhandled exception occurs in the page, the Page class would automatically perform a redirect to the specified page. If a value is not specified, the exception is assumed to be unhandled, wrapped in a new HttpUnhandledException and then thrown, propagating it to the next higher level.

Application Level

Use the customErrors section in web.config.

This section lets you specify the error page to which the user should be redirected to when an unhandled exception propagates in the application level. This section specifies error pages for both default errors as well as the HTTP status code errors.

<customErrors mode="On" defaultRedirect="/WebTest/ErrorPages/AppError.html">
    <error statusCode="404" redirect="/WebTest/ErrorPages/404.html" />
</customErrors>

The mode attribute specifies whether to show user-defined custom error pages or ASP.NET error pages. Three values are supported for this attribute:

  • RemoteOnly - Custom error pages are shown for all remote users. ASP.NET error pages with rich error information are displayed only for local users.
  • On - Custom error pages are always shown, unless one is not specified. When a custom error page is not defined, an ASP.NET error page will be displayed which describes how to enable remote viewing of errors.
  • Off - Custom error pages are not shown. Instead, ASP.NET error pages will be displayed always, which will have rich error information.

It's a bad idea to give users more information than what is required. ASP.NET error pages describe technical details that shouldn't be exposed. Ideally, the mode attribute thus should not be set to Off.

The defaultRedirect attribute specifies the path to a generic error page. This page would typically have a link to let the user go back to the home page or perform the request once again.

Each error element defines a redirect specific to a particular HTTP status code. For example, if the error is a 404 (File Not Found), then you could set the error page as FileNotFound.htm. You could add as many error elements in the customErrors section as required, each of which specifies a status code and the corresponding error page path. If ASP.NET can’t find any specific error element corresponding to a status code, it would use the value specified in the defaultRedirect attribute.

Notes

  • The settings specified in the page level (errorPage attribute) would override those specified in the customErrors section. The reason is because errors in the page would be handled by the Page class first, which might thus prevent the exception from being propagated to the application level. It’s only when the Page class fails to handle the exception that the values set in customErrors come into scope.
  • All these settings mentioned above apply only for requests that are made for ASP.NET files. More specifically, these settings would work only for requests for files with extensions that are mapped to the aspnet_isapi. For example, if you request for an ASP or JPG file (extensions that are not mapped to aspnet_isapi) which does not exist, then these settings won’t work, and the standard error page specified in IIS would be displayed. To modify this behavior, either map the required extensions to aspnet_isapi or modify the custom error pages specified in IIS.

Handling exceptions

There are different levels where you could handle exceptions.

  • Locally (method level), where exceptions could be thrown.
  • Page level by handling the Page.Error event.
  • Application level by handling the HttpApplication.Error event.
  • HTTP Module level by handling the HttpApplication.Error event.

Local error handling

Wrap code that might throw exceptions in a try-catch-finally block.

If you can recover from the exception, then handle it in the catch block. If the exception cannot be recovered from locally, let the exception propagate to higher levels by throwing it. If the exception cannot be recovered from locally, but additional information can be provided, then wrap the exception with the new information and throw the new exception. This method is used when you use custom exceptions. Place the clean up code in the finally block.

Find more information on exception handling best practices available in MSDN.

Note: The more exceptions you catch and throw, the slower your application would run. This is more significant in web applications.

Page Level

Attach a handler to the Page.Error event. In C#, you will have to write the event wire up code yourself in the Page_Load method.

When an exception goes unhandled in a page, the Error event of the Page class gets triggered.

Typically, the first action you would perform in this handler would be to obtain the exception thrown, by using the Server.GetLastError method. This method would return a reference to the last Exception object that was thrown.

After you get the Exception object, you will want to redirect the user to an error page. We could make ASP.NET do the redirection by using the errorPage attribute of the Page (design time) or by using the Page.ErrorPage property (runtime). Obviously, the choice here would be to programmatically set the value using the Page.ErrorPage property in the event handler.

private void WebForm1_Error(object sender, EventArgs e)
{
    // Get the last exception thrown
    Exception ex = Server.GetLastError();

    // Do something with the exception like logging etc.
    
    // Set the error page
    this.ErrorPage = "/ErrorHandling/ErrorPages/BaseError.html";
}

If you do not specify an error page, the exception gets wrapped inside an HttpUnhandledException object and propagates. If you don’t want the exception to be wrapped, then simply throw the last exception, which would force immediate propagation escaping any intervention. However, this would prevent ASP.NET from redirecting the user to a page specific page either. In other words, if you are going to throw the last error (or any exception for that matter), setting the error page will have no effect.

private void BasePage_Error(object sender, EventArgs e)
{
    // Get the last exception thrown
    Exception ex = Server.GetLastError();

    // Do something with the exception like logging etc.

    // The statement below has no significance - it's as good as commented
    this.ErrorPage = "/ErrorHandling/ErrorPages/BaseError.html";

    // Throw the error to prevent wrapping
    throw ex;
}

To reduce redundant code, you could define a base web form page which defines the Page.Error event handler and then wire up code in the constructor, and then make all your Web Form pages derive from this base page. This would save you the effort of writing the error handler in each web form.

Application Level

Attach an event handler to the Application.Error event.

When an unhandled exception leaves a page, it gets propagated to the application level, which would trigger this event.

There are two things you would want to do in an application error handler.

  • Get the last exception thrown using Server.GetLastError.
  • Clear the error using Server.ClearError, to inform ASP.NET that you have handled the error.

If you don’t clear the error, the exception would propagate. However, since there isn't any higher scope where the exception could be caught, ASP.NET is forced to handle it. The way ASP.NET handles the exception depends upon the settings specified in the customErrors section we saw before. If no settings are defined, ASP.NET would use the defaults and display the infamous 'yellow' error page.

HTTP Module Level

Instead of handling application errors in global.asax, exceptions may also be handled by attaching an HTTP Module which would have a handler attached to the Application.Error event. This method would be triggered before the corresponding application handler would be invoked. Such an implementation would be beneficial if you have multiple projects with the same global error handling implementation. In such a scenario, you could create a module and attach it to each web application you have.

All the points we saw in the Page and Application handlers apply to the Module handler as well.

Important Notes

Prevent infinite recursion

If an error occurs in the error handling code, an infinite recursive loop would result, which would soon drag your server down. The reason why this happens is because the new exception would trigger the error event once again which would in turn redirect control to the handler, which would cause yet another exception to be thrown, making an infinite loop.

This might also happen if the error page itself throws an exception. To counter this possibility, making error pages static is a good idea.

Errors may also happen while attempting to redirect to an error page using Server.Transfer or Response.Redirect maybe due to an invalid path. To tackle this scenario, we could wrap the redirection code in a try-catch block. If the redirection fails, then we have nothing more to do other than setting the response code and completing the response, using the Response.StatusCode property and the HttpApplication.CompleteResponse method. This would then be handled by the settings specified in the customErrors section.

Parser Errors

Parser errors are caused due to invalid tags (or similar reasons) in an aspx page. These errors are usually of type HttpParseException. Such errors will not be caught by the Page level handler as page parsing happens before ASP.NET creates the assembly for the aspx page. In other words, parser errors are thrown while ASP.NET reads the aspx file and tries to create its assembly, and hence is way before the corresponding type is created. Thus, such errors will have to be handled in the application scope.

Exception logging and response time

Users need to get responses as quick as possible. Implementation wise, this means that when errors happen, error recovery processes should be quick and users should be redirected or informed of the error as soon as possible. If exceptions are going to be logged to a file or other mediums, then it could take time which would lead to a slow response. Making exception logging an asynchronous process would be a good idea in this respect.

Source Code

The source code is in VS.NET 2003 and the virtual directory is named ErrorHandling. The code demonstrates most of the implementations this article talked about. A few of the items would require you to uncomment and build again, as mentioned in the corresponding sections.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Rakesh Rajan
Web Developer
India India
Member
Rakesh Rajan is a Software Engineer from India working at Technopark, Trivandrum in Kerala. He is a Microsoft MVP and an MCSD (.NET) with a few other certifications, and had been working in .NET for the past 3 years. He graduated majoring in Computer Science during his memorable days at Ooty (a wonderful hill station in Southern India). You can find him posting at newgroups, writing articles, working on his own projects or taking some time off by listening to music by Enya or Yanni, or reading an Archer or Sheldon.
 
Find his online publications here.
 
Rakesh blogs at http://rakeshrajan.com/blog/ and maintains a site http://rakeshrajan.com/.
He used to blog at http://www.msmvps.com/rakeshrajan/.
 
Drop him a mail at rakeshrajan {at} mvps {dot} org.

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   
GeneralMy vote of 5memberSteven.M.Hunt4 Mar '13 - 2:29 
Very nice article, just what I was looking for!
GeneralThread SafetymemberRyuuko7 Aug '12 - 7:32 
A bit of a nit-pick, but Server.GetLastError() is not thread-safe. You should be using HttpContext.Current.Error, instead.
GeneralMy vote of 4memberkavyab2 Jun '12 - 8:42 
thank u 4 ds article!!! i understood it very well..Smile | :)
GeneralNice articlememberVirat Kothari7 Jun '10 - 7:48 
Hi!,
 
This is really cool one. It is all about exception handling, really helpful. Keep it up.
Regards,
Virat Kothari

GeneralCannot understand page level error handlingmembervishwjeet9 Sep '09 - 1:23 
Hi .. i am not able to understand why would we get the systemexception at the pagelevel .. assign a redirect page .. and then again throw the exception ..
also .. u have said that we have to manually wireup the event .. can you put a code snippet for that too?
GeneralPropagate error in higher levelmember5552 Jun '09 - 20:49 
In my web application i want to handle unhandled exception by customer error page.so i have some custom static error pages.But in application level i write code to log the exception.this is working.i have found the error log and see custom error page.
 
what i want is that in my web page code behind file i used try catch in custom method and throw exception(By 'throw ex')to propagate in page level page_error.But when an error occur it
stop executing in catch block 'throw ex' as highlighted yellow color.it is not propagating in page level.but when i press F5 ,it goes to page level and application level and finally custom error page which i want.
 
why it stop executing in catch block and not propagating in higher level???what is the problem?please help me.
QuestionHow can you handle this in Error 404memberMico_Perez_II11 Feb '09 - 19:29 
Hi there
 
How can we handle this url "www.test.com/default.aspx/test.aspx"
I already tried to put this on web.config



Seems that it the asp can't handle this.
Any thoughts?
 
Programmer's C# { Do it Better;}

GeneralCheck this article for more indepth discussion on handling exception in asp.netmemberDotNetGuts10 Sep '08 - 12:29 
indepth discussion on handling exception in asp.net
 
DotNetGuts
"Lets Make Programming Easy"
 
Logon to http://www.dotnetguts.blogspot.com
 
Join .Net Developer's Community http://groups.yahoo.com/group/dotnetguts/join

QuestionHelp!This type of error can't be handled?membermnongkhlaw26 Jun '08 - 2:34 
URL : http://www.codeproject.com/KB/aspnet/%20/ErrorHandlingASPNET.aspx
 
Note the %20 I deliberately inserted in the URL. I got :
 
Server Error in '/' Application.
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
 
Requested URL: /KB/aspnet/ /ErrorHandlingASPNET.aspx
 
Question : How do I handle such types of errors to display me a friendlier page?
GeneralEvent Handler in ASP.NETmemberMember #29598585 Feb '07 - 18:12 
Smile | :) How to use the event handler in asp.net? and exactly keypress event how to use it?
 
rajaram
GeneralHttpApplication.CompleteResponse ?? [modified]memberKrishanChaminda1 Nov '06 - 15:11 
Hi
 
The article is quite useful and helpful. However I found some incorrect methods calls, and incomplete explanation.
 
In the section “Prevent infinite recursion” I guess you meant HttpApplication.CompleteRequest not “CompleteResponse”, because there is no such method in HttpApplication.
 
Use of Response.StatusCode is not mentioned properly. There are many status codes in “HttpStatusCode” enum. (This enum is located in System.Net; name space). And I don’t see a point changing this status, Where as CompleteRequest() will do the needful.
 
Finaly, its best to mentioned where we can find the CompleteRequest() method on the page. It can be located in; Context.ApplicationInstance.CompleteRequest();
 
Cheers

 
Krishan Ariyawansa
 

 
-- modified at 22:48 Wednesday 1st November, 2006
QuestionGetting Error Code returned by an errormemberDownBySpj7 Oct '06 - 1:26 
I have to change some of my logic based on the error returned by a code. I have to first try to do a simple insert in a table. If it throws a error then i will have to change the statement(update) and again try the insert. How can i do this. Sorry if i hv posted the question in the wrong discussion board. It may be a quesiton of c# also
QuestionIt is not working for incomplete URLmemberDelhiRainbow24 Sep '06 - 23:23 
It is not working for incomplete and not exist directory in URL like www.abc.com/notexist but it is working fine for ww.abc.com/notexist/notfound.aspx
 
How can i resolve this problem?
 

 
Pankaj Gupta

QuestionHow to set variable before Page.Error occursmemberChris Becker22 Aug '06 - 20:24 
I have a function in my base page that looks like this:
    Private Sub Page_Error(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Error
        If Me.m_CatchHttpRequestValidationException Then
            If Server.GetLastError.GetType() Is GetType(System.Web.HttpRequestValidationException) Then
                HttpContext.Current.Items("HttpRequestValidationException") = True
                Server.ClearError()
            End If
        End If
    End Sub
 
The problem is that I am not able to set Me.m_CatchHttpRequestValidationException before Page.Error is triggered. I have tried Page.Init and Page.PreInit in the derived page classes.
 
Anyone know of a way to set Me.m_CatchHttpRequestValidationException before page.error occurs?
 
What I am trying to do is to allow some derived pages to handle the HttpRequestValidationException specifically with possibly a customvalidator that will check HttpContext.Current.Items("HttpRequestValidationException")

 
http://www.onlinescorekeeper.com/

GeneralError Handlingmemberntuyen0111 May '06 - 8:00 
Hi All,
 
I create a long form, on the form i have couple fields using the control "RequiredFieldValidator". Now the user click on the "submit" button,
if the user does not enter the value for the required then error will display (it works fine), but the user does not see the error unless they scroll up the form. Is there a way in the asp.net to make the page go up to the top or to the error field so the user does not have to scroll up or wonder what going on

 
Thank You
Regards,
ntuyen01
General401 error handlingmembercanasdaq_deals4 May '06 - 9:35 
Rakesh,
It was a very interesting article. I am trying to do a generic 401 error handler for multiple websites. I used in the web.config file. It is working fine for 404 errors, but doesnt seem to work for 401 errors. can you please tell me how to do this kind of handling and also tell me how to do HTTP Module level handling. I would really appreciate your reply. Thanks for your help in advance.
QuestionDebugging problem on exceptionmemberArvin Boggs5 Sep '05 - 17:17 
In debug mode, exceptions do not pause execution in Visual Studio. Instead, execution continues and IE shows the "yellow" detailed error page. Plz tell how to setup VS and IIS so to break.
 
This is my current setup.
- breakpoint are hit
- "Unhandled exceptions" in Debug->Exception is set to "Break into debugger"
- if "Handles exception" in Debug->Exception is set to "Break into debugger, instead of the default "Continue", only then exceptions are hit.
- I can step-by-step through my code.
 
Any information will be appreciated.
GeneralDoesn't seem to be workingmemberDave Midgley9 Aug '05 - 6:49 
I am developing my first ASP.NET project. I've got a first try working on my local PC but when I transferred it to the remote server and accessed it over the web I got an error page:
---------------------------
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 <customErrors> tag within a "web.config" configuration file located in the root directory of the current web application. This <customErrors> tag should then have its "mode" attribute set to "Off".
---------------------------------
 
I did exactly what it (and Rakesh Rajan) said I should do - I changed the customErrors tag in my web.config from mode=RemoteOnly to mode=off. However, it has made absolutely no difference. I just get the same generic error page. I've tried deleting IE temporary files but that didn't help either.
 
Can anyone help?
 
Dave
GeneralI actually implemented some of this - Thank youmembervmo3d22 Jul '05 - 4:21 
"...To reduce redundant code, you could define a base web form page which defines the Page.Error event handler and then wire up code in the constructor, and then make all your Web Form pages derive from this base page. This would save you the effort of writing the error handler in each web form....."
 
Thank you so much, I actually implemented this and now I can see exactly where the error happens. Before I used to only check in Global.aspx and could not trace error origins to the specific method at fault.
 
Thank you,
Vlad
GeneralRe: I actually implemented some of this - Thank youmemberRakesh Rajan22 Jul '05 - 4:44 
Glad to know that Vlad! Smile | :)
 
Rakesh

GeneralReally good artivle RakeshsussAnonymous21 Jul '05 - 8:32 
Really good artivle Rakesh... You covered all aspects of error handling into one article...
Thanks...
 
Jim
GeneralRe: Really good artivle RakeshmemberRakesh Rajan22 Jul '05 - 4:45 
Thanks a lot Jim! Smile | :)
 
Rakesh

GeneralExcellent ArticlesussAtmaram B.14 Jun '05 - 2:52 
Really good artivle Rakesh... You covered all aspects of error handling into one article...
Thanks...
GeneralRe: Excellent ArticlememberRakesh Rajan14 Jun '05 - 6:16 
Thanks Atmaram!
 
Rakesh

GeneralThanks - you tied this all together!memberEric Engler8 Jun '05 - 11:31 
Thanks for this article. You tied the main error handling details together in one article!

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 5 Jun 2005
Article Copyright 2005 by Rakesh Rajan
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid