Stand-alone EXE or a Windows Service version).">
 
  •      Powered by
 
New Page 1

Custom Errors, IIS for Classic ASP and ASP.NET

Introduction

This article covers how to setup and use the Custom Errors options offered in IIS (Internet Information Server) and ASP.NET to track 404, 500 errors. For all types of users, a “404 webpage not found” or “500 internal server errors” are frustrating. From the end-user experience, this could potentially have the visitor not come back to your website. This article introduces a technique to capture these errors to a database.

Classic ASP and ASP.NET have different ways to control the user experience when an error occurs. Classic ASP relies on IIS “Custom Errors” section to redirect when an error happens. ASP.NET uses settings in the <customErrors> section contained in a web.config. This can make it difficult if your website has a combination of HTML, ASP and ASP.NET webpages. Having different ways to configure can be impossible sometimes if you are in a shared hosted environment.

The solution I came up with centralized all errors to a single database regardless of extension. We will discuss how to setup, record and report on these errors. Hopefully this will help make the end user experience more enjoyable and keep them coming back day after day.  

Webpage to process, record the error to a database.

First thing to do is develop a dynamic webpage (ASP or ASP.NET) that will capture and record to a database. For this article, my intention isn’t to discuss the complexity of making the error page. This could be an entire article but for our purposes, this will capture and record to the database.

For this article, we will use the pages I used on ASPFree.com. At the time it was easier to have separate pages for the 404, 500 errors. This could easily be done in a single webpage. To get started, create create two files named 404.aspx, 500.aspx, copy and paste the code and place in the root of your website.

404 webpage – 404.aspx

<%@ Page Language="VB" Trace="True" %>
<%@ Import Namespace="System.data" %>
<%@ Import Namespace="System.data.sqlclient" %>
<%@ Import Namespace="system.configuration" %>
 
<script language="VB" runat=server>
Sub Page_Load(Sender as Object, E as EventArgs)
If (Not Request.QueryString("aspxerrorpath") Is Nothing) Then
Dim objConn As SqlConnection = New SqlConnection(ConfigurationSettings.AppSettings("dbConn"))
dim pg as string = Request.QueryString("aspxerrorpath").ToString()
dim cmd as SQLCommand = new SqlCommand("sp_tblNotFoundPages", objConn)
cmd.CommandType = CommandType.StoredProcedure
 
cmd.Parameters.Add(New SqlParameter("@strPageLookedfor", SqlDbType.VarChar, 500))
cmd.Parameters("@strPageLookedfor").Value = pg
 
cmd.Parameters.Add(New SqlParameter("@strTypeOfError", SqlDbType.VarChar, 50))
cmd.Parameters("@strTypeOfError").Value = "404"
 
objConn.Open()
cmd.ExecuteNonQuery()
objConn.Close()
End If
End Sub
</script>
 
<html>
<head></head>
<body>
This page has not been found, we have record this error and notified webmaster.
</body>
</html>

500 webpage – 500.aspx

<%@ Page Language="VB" Trace="True" %>
<%@ Import Namespace="System.data" %>
<%@ Import Namespace="System.data.sqlclient" %>
<%@ Import Namespace="system.configuration" %>
 
<script language="VB" runat=server>
Sub Page_Load(Sender as Object, E as EventArgs)
If (Not Request.QueryString("aspxerrorpath") Is Nothing) Then
Dim objConn As SqlConnection = New SqlConnection(ConfigurationSettings.AppSettings("dbConn"))
dim pg as string = Request.QueryString("aspxerrorpath").ToString()
dim cmd as SQLCommand = new SqlCommand("sp_tblNotFoundPages", objConn)
cmd.CommandType = CommandType.StoredProcedure
 
cmd.Parameters.Add(New SqlParameter("@strPageLookedfor", SqlDbType.VarChar, 500))
cmd.Parameters("@strPageLookedfor").Value = pg
 
cmd.Parameters.Add(New SqlParameter("@strTypeOfError", SqlDbType.VarChar, 50))
cmd.Parameters("@strTypeOfError").Value = "500"
 
objConn.Open()
cmd.ExecuteNonQuery()
objConn.Close()
End If
End Sub
</script>
 
<html>
<head></head>
<body>
This page had an error or it’s not found. Please retry again if you feel this was in error.
</body>
</html>
 

 
How to setup a web server to use custom Errors section
 
Log into server as an Administrative user 
-In IIS 6 use this path – Click Start, Program Files, Administrative Tools, and Internet Information Services (IIS) Manager
-In IIS 5 use this path – Click Start, Program Files, Administrative Tools, and Internet Server Manager
-Right Click on your website, chose properties
 
Note: This procedure needs to be done on both the 404 and 500 errors setting.
 


-Select (for example 404) –
-Click Edit
-Select Message Type – URL
-In the URL field – type in /404.aspx (this can be any webpage in the root of your website); this webpage will contains the logic to record errors to a database.

 



-Click OK
-Click OK again.

How to Setup ASP.NET to capture 404 and 500 errors
 
Unlike HTML and ASP web-pages that rely on IIS, ASP.NET uses the <customErrors /> section in a web.config how to handle an error. There are three potentials values, “On”, “Off” and “RemoteOnly”. These values are case sensitive and for our article we will need the value to be “On”. To read more in-depth about the web.config and these settings, here is an article on MSDN. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/gngrfcustomerrorssection.asp

Here is our web.config.

<configuration>
    <appSettings>
        <add key="dbConn" value="server=dbserver;uid=your UID;pwd=YourPWD;Database=YourDB" />
    </appSettings>

<system.web>
    <customErrors defaultRedirect="/404.aspx" mode="On">
        <error statusCode="404" redirect="/404error.aspx" />
        <error statusCode="500" redirect="/500error.aspx" />
        </customErrors>
        </system.web>
</configuration>

Setting up the Database
 
The last step is setup the Database with the Tables and stored procedures that will store the information. A side note about capturing errors, when I first implemented this on ASPFree.com, I just captured the raw detail data. This meant if a webpage errored 10 times in a day, there were 10 records in the database.  With over 15,000 unique documents this made for several thousand records. My original goal was to capture the *raw* data and do a roll-up process later on. This added a lot of complexity and made the database grow to about 500 Meg. Also trying to roll-up a lot of records into a summary report was time-consuming and database intensive.

I found a much simpler and more effective way. I changed the stored procedure logic to record just a single database record for each webpage per day and then added a column to record raw number of hits for each page. The one drawback I couldn’t report when and what website was causing the error. For example, if a search engine such as Google or Yahoo had a bad link indexed, I would need have to search my IIS log files to see who was sending the bad link. There was no perfect solution without adding more logic, for my needs this technique provided more than enough information to help keep 404 and 500 errors to a minimum.

You will need your ISP or access to SQL Enterprise manager or SQL Query Analyzer to run the .SQL file to add the table and stored procedure.

Table

CREATE TABLE [dbo].[tblNotFoundPages] (
[Id] [int] IDENTITY (1, 1) NOT NULL ,
[pagelookedfor] [varchar] (500) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[DateofError] [datetime] NULL ,
[numOfHits] [int] NULL ,
[TypeOfError] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
) ON [PRIMARY]
GO
 
ALTER TABLE [dbo].[tblNotFoundPages] ADD
CONSTRAINT [DF_tblNotFoundPages_numOfHits] DEFAULT (1) FOR [numOfHits],
CONSTRAINT [PK_tblNotFoundPages3] PRIMARY KEY CLUSTERED
(
[Id]
) WITH FILLFACTOR = 90 ON [PRIMARY]
GO
 
Stored Procedure
 
CREATE PROCEDURE dbo.sp_tblNotFoundPages
(
@strPageLookedfor varchar(500),
@strTypeOfError varchar(50)
)
 AS
Declare @chkRecord int
Declare @numOfHits int
Declare @DateOfError datetime
set @DateOfError = convert(char(10), getDate(), 101)
If exists (select Id from tblNotFoundPages where pagelookedfor = @strPagelookedfor and DateOfError = @DateOfError)
Begin
set @numOfHits = (select numOfHits from tblNotFoundPages where pagelookedfor = @strPagelookedfor and DateOfError=@DateOfError) + 1
UPDATE tblNotFoundPages
SET numOfHits = @numOfHits
WHERE pagelookedfor = @strPagelookedfor and DateOfError=@DateOfError
End
ELSE
INSERT INTO tblNotFoundPages(pagelookedfor, TypeOfError, DateOfError) VALUES (@strPagelookedfor, @strTypeOfError, @DateOfError)
GO


Conclusion
 
We hope you find this helpful in tracking down errors on your website. I used this solution to help track down errors on broken links, missing images or coding errors. The most useful tool in finding errors would occur when a “web-bot” would index ASPFree. If everything is setup correctly, you should be able to type in a browser http://yoursite.com/PageNotFound99.asp or http://yoursite.com/PageNotFound99.aspx and these entries will be recorded to the database.
 

 

tio

Terms of Use | Privacy Statement ©2005-2006 IISLogs.com. All rights reserved - Powered by IIS7 - info @ www.IIS.net