ASP and the Error Handler

By Richard Bundock


ASP pages are so easy to put together that sometimes developers have not thought through the problems associated with errors. Error handling can help your application to be more robust. I have often come across commercial sites written in ASP that fail to have any sort of error handling.


Types of Error



There are 3 main types of errors:


  • Compile-time errors

    These errors are usually in the syntax of the code and stop the ASP from compiling. You may have experienced this if you left the closing “Next” statement off of a “For” loop.

  • Runtime errors

    These happen when you try to execute the ASP page. For example, if you try setting a variable outside its allowed range.

  • Logic errors

    Logic errors are harder to detect. The problem lies within the structure of the code, and the computer cannot detect an error. These types require thorough testing before rolling out the application.

As compile-time errors are always trapped and logic errors are only found through thorough testing. This leaves us to worry only about runtime errors. These can stop the execution of your page and leave the user with a lot of non-user-friendly text on the screen.


Crashing Through


So how do we handle runtime errors in ASP? Let’s start by using the only command that ASP has to help us – On Error Resume Next. The documentation tells us that:


“If you don’t use an On Error Resume Next statement, any runtime error that occurs is fatal; that is, an error message is displayed and execution stops.”


This is the key. Runtime error stop the page execution and you get a nasty non-user-friendly message like:




Microsoft OLE DB Provider for ODBC Drivers error 80004005
[Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified
/test.asp, line 60



So, with the On Error Resume Next function set at the top of the page, all errors are ignored and execution continues with the next line after the error. That’s all very well and good, but the user does not see any error. This can be even more frustrating when the results appear to not conform to expectations. To avoid this, you need to handle the error at some point within the page.


Handling the Error


In ASP, the best way to handle errors is to place code at the bottom of each page that can display an appropriate message to the user. I also recommend using the buffer on every page. If an error occurs, the contents of the page can be cleared before displaying error details. This should be less confusing for the user and you. Here is some sample code:





<%@ LANGUAGE=”VBScript” %>

<% ‘ Turn on page buffering
Response.Buffer = True

‘ Turn On Error Handling
On Error Resume Next

‘ Your ASP Page code

%>

<% ‘ Error Handler
If Err.Number <> 0 Then

‘ Clear response buffer
Response.Clear

‘ Display Error Message to user %>

<HTML>

<HEAD>
<TITLE></TITLE>
</HEAD>

<BODY BGCOLOR=”#C0C0C0″>

<FONT FACE=”ARIAL”>An error occurred in the execution of this ASP page<BR>

Please report the following information to the support desk<P>
<B>Page Error Object</B><BR>
Error Number <%= Err.Number %><BR>
Error Description <%= Err.Description %><BR>
Source <%= Err.Source %><BR>

LineNumber <%= Err.Line %><BR>

</FONT>

</BODY>
</HTML>

<% End If

%>





As you can see from above, I first set the On Error Resume Next so that errors don’t stop page execution. Once the execution point falls to the Error Handler I clear the page from memory and return a complete error page to the user. This can say anything. It doesn’t have to offer a printout of the error object or ask the user to contact the support desk. You could of course add some code to log the error in a file or a database.


Error Handling and Databases



Adding a database to the error-handling equation can complicate things. Assume that we have an ASP page where a couple of calls are made to a database to display some data, but then an insert/update query is executed at the bottom of the page. Now, because we have the On Error Resume Next switched on, if an error occurs in the select queries, the insert/update will still fire. This can cause data integrity problems within the database or fail to give the desired functionality. To prevent this, a check for an error must be made before any insert/update/delete queries are fired. To achieve this, wrap the database call up. It would look something like this:




If Err.Number = 0 And objConnection.Errors.Count = 0 Then

‘ Fire the database query, because there are no errors
Set rstResults = dbData.Execute(txtSql)

End If





More Advanced Error Page



You can also print out more information if an error occurs when execution reaches the bottom of the page, including the page error object properties and the database connection error object properties. This will offer more details on exactly what errors have been returned from the database connection. You will need to add the following to the error page code used above:





<% ‘ Error Handler
If Err.Number <> 0 Then

‘ Clear response buffer
Response.Clear

‘ Action sensitive to error
Select Case Err.Number

Case “” ‘ Specific error messages
‘ Placeholder for specific error message code
‘ You can handle custom errors here

Case Else ‘ General Error Response

If IsObject(objConnection) Then

If objConnection.Errors.Count > 0 Then %>

<B>Database Connection Object</B>

<% For intLoop = 0 To objConnection.Errors.Count – 1 %>

Error No: <%= objConnection.Errors(intLoop).Number %><BR>
Description: <%= objConnection.Errors(intLoop).Description %><BR>

Source: <%= objConnection.Errors(intLoop).Source %><BR>
SQLState: <%= objConnection.Errors(intLoop).SQLState %><BR>
NativeError: <%= objConnection.Errors(intLoop).NativeError %><P>

<% Next
End If

End If

If Err.Number <> 0 Then %>

<B>Page Error Object</B><BR>
Error Number <%= Err.Number %><BR>
Error Description <%= Err.Description %><BR>
Source <%= Err.Source %><BR>

LineNumber <%= Err.Line %><P>

<% End If

End Select
End If
%>




The code above also allows for more than one error in the database connection object, which there often is. It just loops through the error collection in the database connection object. You will also notice that a Select Case statement allows you to handle a specific page error rather than having you jump into the generic error response.

Redirects with the Error Handler



One more thing to watch out for is redirecting from the page before the execution point reaches the error handler. If a redirect happens, then the Error Handler is rendered useless. So you need to wrap any code that redirects, just like you did for the database calls. Here is an example:





If Err.Number = 0 And objConnection.Errors.Count = 0 Then

‘ OK to redirect
Response.Clear
Response.Redirect “<URL Here>”

End If






Making the Code Neater



To make the code in your application neater, first make the error page an Include file. You can then drop this into any page easily. You will have to follow some rules, however, while your are developing your code. Points to remember when implementing error handling are:


  • Add On Error Resume Next to your page. (Make it the first command after the language declaration.)
  • Always wrap your database calls with checks on both error objects.

  • Always wrap any redirects with checks on both error objects.
  • Make sure you include the error-handler code at the bottom of the page.

I hope this article helps you to implement strong error handling in ASP pages.


About the Author



Richard Bundock has been consulting on Active Server Page issues for more than two years. He is now a freelance consultant specializing in ASP and VB. A certified Microsoft Professional, Richard is currently working on one of the largest ASP Intranet developments in the UK. He hopes to gain his MCSD and MSCE during the summer. His email address is [email protected] .

More by Author

Must Read