Customize Default ASP.NET Exception Handling

ASP.NET has a default exception-handling system, but it ain’t pretty — unless you take the time to customize it.

asp:feature companion


TECHNOLOGIES: Exception Handling


Customize Default ASP.NET Exception Handling

ASP.NET has a default exception-handling system, but it ain't pretty - unless you take the time to customize it.


By Don Kiely

Like pretty much every development environment in the history of computing, ASP.NET has a default exception handling system, which is unlikely to be acceptable for any production application. Suppose you have this code in a Page's Load event procedure:


Dim x As Integer = 44

Dim y As Integer = 31

Dim z As Double

Dim zi As Double


z = x / y

zi = x \ y

lblResult.Text = "When x is " & x.ToString _

   & " and y is " & y.ToString _

   & ", x / y is " & z.ToString _

   & ", and x \ y is " & zi.ToString & "."


Now suppose somehow the variable y in the previous code is 0 instead of 31. Interestingly, the result of the floating-point division assigned to z is a special value of infinity, so the line z = x / y doesn't throw an error. But the line zi = x / y does throw an exception, which is not handled in this procedure or anywhere else in the application. So the ASP.NET default behavior kicks in.


What the user sees depends on where the application is running. If the browser is running on the same machine as the application, which is a common scenario during development, the user sees Figure 1. In many cases, this provides enough information to find what went wrong so you can fix the problem.


Figure 1. With the default configuration out of the box, a user running an application with an unhandled exception gets a fair bit of information about what caused the problem, including a stack trace.


If the browser is running on a remote machine, such as when an application goes into testing or production and real users are hitting the server, the same error will present the user with Figure 2.


Figure 2. Still using the default ASP.NET configuration, a remote user will get this less-than-useful page. Unless you hate your users, decide right now that no one will ever see this in an application of yours.


I don't know about you, but I'll work awfully hard to keep my users from seeing a message that seems to imply that whatever idiot set up this application didn't configure it right. That's not the message I want to convey, no matter how wrong (or right) it might be!


This default behavior is affected by the customErrors element in web.config. The default behavior is equivalent to this line in the section of web.config:



This tells ASP.NET that when an unhandled exception occurs, it should present remote users with the "bad configuration" page, and local users should get the detailed debugging information. Because this is the default, the lack of a element - or even no web.config file at all - gives you this behavior.


The mode attribute has two other settings: On and Off. On simply means all users get the somewhat useless "bad configuration" page; Off means all users get the detailed debugging page. (In the sample application, set Default.aspx as the start page and see the instructions there for modifying web.config to explore these behaviors.)


You can customize this default behavior further by using the defaultRedirect attribute of :


mode="On" />


Now when an unhandled exception occurs, the user is presented with whatever content you provide in the static GenericError.htm page, such as the one I've set up in Figure 3. Note that the mode attribute affects behavior in the same way described above, so On means every user sees GenericError.htm, Off means no one does, and RemoteOnly means only remote users see it while local users get debugging information.


Figure 3. By redirecting users to a custom error page, you can soften the blow a bit when something goes wrong.


This is a bit better because it presents the user with something consistent with the visual design of the application. You can control what the page says, and everyone feels better (hopefully).


Notice in the address bar in Figure 3 that ASP.NET includes a querystring parameter, aspxerrorpath, which includes the path of the offending aspx page. If you want, you could incorporate this in the error page using an aspx page instead of static HTML:



This results in the error page shown in Figure 4, which includes a new middle paragraph.


Figure 4. Because ASP.NET includes the aspxerrorpath querystring attribute, you can include information about which page caused the error.


This simple example uses inline code to display the query string information. You can, of course, write whatever complex code you need to present whatever makes sense in a particular application:


<% If Not Request.QueryString("aspxerrorpath") Is Nothing %>


    In case you didn't know, the error arose from




<% End If %>


Another configuration option with is to include different error pages, either static HTML or dynamic aspx pages, in response to different kinds of errors.


In the element below, HTTP errors 404 (page not found) and 500 (internal server error) are redirected to their own custom error pages (Error404.htm and Error500.htm in this case), while all other errors still go to GenericError.aspx.





One thing to be careful of here is that HTTP status code 500 acts as a sort of catch-all for most run-time code errors. So in the sample application, the divide-by-zero error is redirected to Error500.htm rather than GenericError.aspx.


With this technique, you also can define custom errors in IIS and hook into them with custom error pages. You aren't limited to the predefined HTTP errors.

Don Kiely is senior information architect for Information Insights, a business and technology consultancy in Fairbanks, Alaska. E-mail him at mailto:[email protected].




Hide comments


  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.