I recently took over an ASP.NET application
utilized by a large healthcare company that wanted to implement
additional functionally and correct many existing problems. The
company didn’t have a system for gracefully handling errors; that
is, any error resulted in the display of the default error page.
With that in mind, I chose to make it a top priority to add more
user-friendly error pages.
Error messages
By default, ASP.NET displays error messages
that include the .NET error description along with a stack trace.
For example, here is an error message:
Server Error in ‘/Test’ Application.
SQL Server does not exist or access denied.
Description: An unhandled exception occurred during the execution
of the
current web request. Please review the stack trace for more
information about
the error and where it originated in the code.
Exception Details: System.Data.SqlClient.SqlException: SQL Server
does not
exist or access denied.
Source Error:
Line
100: } catch(Exception
ex) {
Line
101:
ExceptionManager.Publish(ex);
Line
102: throw
ex;
Line
103: }
Line 104: }
Source File: c:\cvone\web
application\secure\status.aspx.cs Line:
102
Stack Trace:
[SqlException: SQL Server does not exist or access denied.]
Test.Application.Page_Load(Object sender, EventArgs e) in
c:\test\web
application\test.aspx.cs:102
System.Web.UI.Control.OnLoad(EventArgs e) +67
System.Web.UI.Control.LoadRecursive() +35
System.Web.UI.Page.ProcessRequestMain() +725
Version Information: Microsoft .NET Framework
Version:1.1.4322.573; ASP.NET
Version:1.1.4322.573
There’s a lot of information in this error
message. First, the exception is thrown when attempting to access
SQL Server. The message includes a code excerpt, along with the
local path (on the server) to the file. The stack trace signals
where the specific error occurred, and the last line tells you the
.NET Framework version utilized.
This information is great if you’re a developer
because it tells you why and where the error occurred. On the other
hand, this information may be confusing to the average user. They
will not understand the displayed text, and it may result in more
support calls or even in them possibly abandoning the site. Also,
hackers may unscrupulously use the information that’s in the error
details.
One particularly vulnerable area is the section
of the error page that displays the lines of code. If this includes
names and passwords (although I don’t recommend it) in code that
accesses a database, a person may easily gain access to other
resources, such as a database server. Also, the line that details
the file location (not the Internet Information Services virtual
directory) on the server provides valuable information if the
server is compromised.
Create your own
ASP.NET offers a simple way to provide an
alternative to the default error page. You may create a custom
error page and tell Internet Information Services to display it
instead of the default. The web.config file with the customErrors
element contains the setting:
<customErrors mode=”On”
defaultRedirect=”errors/ErrorPage.aspx”>
</customErrors>
This tells the system to display the custom
error page (errors/ErrorPage.aspx) instead of the default error
page. Since errors may occur at any place within the application,
the error page should be available to all users (security access of
public). I usually create a public errors directory and place the
appropriate resources within it.
The defaultRedirect attribute contains the path
to the error page; in addition, the mode attribute tells the system
if and how error handling is enabled. Here are the possible values
of the attribute:
- On: All errors utilize the custom error page.
- Off: Custom error pages aren’t used.
-
RemoteOnly: The custom error pages are used for clients other than
the local machine. This is good for debugging a production
application. It allows you to sit at the server and view errors
while clients receive the custom error pages.
A custom error page may be a simple HTML file
or an ASPX file–it depends upon your requirements. For example,
you may use the following HTML as a custom error page:
<html>
<head>Custom Error Page</head>
<body>
<h1>An error occurred. Please try again
later.</h1>
</body><html>
Handling specific errors
The customErrors section of the web.config file
allows you to handle individual errors differently. Errors are
distinguished by their HTTP error codes.
Let’s look at a few of the more common
errors:
-
400–Bad request–The request could not be understood by the
server. - 401–Unauthorized–The request requires authentication.
-
404–Not found–The server has not found anything matching the
request. -
500–Internal server error–The server encountered an unexpected
condition that prevented it from fulfilling the request.
A complete HTTP status code listing is available
online. You may expand the customErrors section of the
web.config file to handle specific error codes. You can achieve the
expansion by adding error elements under the customErrors element.
The following sample shows how you may accomplish this:
<customErrors mode=”RemoteOnly”
defaultRedirect=”errors/ErrorPage.aspx”>
<error statusCode=”400″ redirect=”errors/ErrorPage400.aspx”
/>
<error statusCode=”401″ redirect=”errors/ErrorPage401.aspx”
/>
<error statusCode=”403″ redirect=”errors/ErrorPage403.aspx”
/>
<error statusCode=”404″ redirect=”errors/ErrorPage404.aspx”
/>
<error statusCode=”408″ redirect=”errors/ErrorPage408.aspx”
/>
<error statusCode=”500″ redirect=”errors/ErrorPage500.aspx”
/>
<error statusCode=”503″ redirect=”errors/ErrorPage503.aspx”
/>
</customErrors>
This sample handles each specific error with
the corresponding page. The statusCode attribute of the error
element designates the error, and the redirect attribute defines
the page to use. This allows you to tailor the error message based
upon the error encountered. The default error page handles any
error that isn’t specified.
Custom error pages may be developed/used on
individual applications, but Internet Information Services allows
error pages to be designated server-wide via its properties.
Improving user experience
We all design applications with the goal of no
errors, but they do occur. Providing detailed information with
user-friendly error pages can help prevent support calls and reduce
the amount of information that less-than-faithful users may
use.
TechRepublic’s free .NET newsletter, delivered each Wednesday, contains useful tips and coding examples on topics such as Web services, ASP.NET, ADO.NET, and Visual Studio .NET. Automatically sign up today!