The ASP Emporium
Free Active Server Applications and Examples by Bill Gearhart
Online since Friday January 7, 2000

 home > code > tutorials > Learning the <CODE>ASPError</CODE> Object - ASP's 7th built in object

enter a phrase to search: (advanced search)


 h o m e 

 w h a t 's  n e w 

 a l l   c o d e 
  .net:
    • Fundamentals
    • C# Classes
  classic asp:
    • Code Library
    • ASP Apps
  general:
    • Tutorials
    • SQL

 d o w n l o a d s 

 u s e r   f o r u m s 

 l i n k s 

 s e a r c h 

 s u p p o r t 


Learning the ASPError Object - ASP's 7th built in object

No more of the old, bland error messages that everyone's used to from the older releases of IIS and ASP. If you're using ASP 3 and IIS 5, you have a new ASP object to work with and might not have even noticed it was there!

The ASPError Object allows you to get detailed error information and provides a handy way to get everything you need to know about an error caused by ASP code.

Now how can we pull this sweet trick off? Well, when an error occurs in code, like this:

<%
err.raise 43254, "myclass object v1.0", "please enter a valid path."
%>

and no error handling is found to handle the error, a couple of things happen. First, the server generates an http code of 500 with a sub-type of 100. This indicates that an ASP error has occurred. At this time, ASP fills the properties of the ASPError Object with information about the error and transfers control to the 500-100.asp file. This file is built into and installed with IIS but you can point that particular error to any file on the server using the IIS console.

I'm getting ahead of myself. First you need to create your error handler page. Often times the best error handler page is a page that pretends that everything's kosher even though something fatal happened during code processing. In other words, a user hits a page and it craps out for whatever reason... Normally the user gets an error message with debugging info. Sloppy. What is the average user going to do with a line number? Instead, print a cool "temporarily updating content or database" message. That way, it looks like we meant for the site to go down just then...

Of course, we need that debugging info because if it's not grabbed then, it's lost forever (of course it will always be in the event logs though). So behind the iron curtain of a flat out lie ("site temporarily down because we're updating content" message), we can do something useful like save the debugging info into a log file. The log file can be as specific as you want it to be as the ASPError object exposes some sweet properties.

Just like any other ASP page, you can do whatever you want in your error handler page but the most important thing will be interacting with the ASPError object. Here's how it works. When ASP transfers control to whatever file is specified to handle the 500-100 error (which is going to be your new custom error handler page), it's like the current error has gone away. The 500 error generated before to call this page is gone so you need to put it back. This step is mandatory and must be the first thing that any error handler page meant to handle 500-100 errors does. It looks like this:

<% @ language="VBScript" %>
<%
Option Explicit
With Response
	.Buffer = True
	.Clear
	.Status = "500 Internal Server Error"
	.ContentType = "text/html"
	.Expires = 0
End With
%>

As you can see above, you must set the http status to a code of 500 as well as set the content-type header to text/html. You don't have to enable the response buffer but it will come in handy for the next part... and it's usually good to force the expiration header to be sent as well so that the page isn't cached.

Now we've put the 500 error back in (that's just by design. On this page, you must specify the http status code or it will be like an error never happened). We'll raise an error in the IIS Event Logs of 500 but the user won't have any idea of what just happened.

The second step is to call a special method of the Server object. This method must be called before anything is written to the browser - that's why the response buffer is turned on above. Calling the GetLastError method of the server object provides you with an instance of the ASPError object with it's read-only properties set and ready to go.

Set objASPError = Server.GetLastError

After this line, you go hog-wild, doing whatever you want with the info about the error... To serve as a guide, here's a listing of all the properties and what they return:

<%
objASPError.ASPCode        'Returns the error code generated by IIS.

objASPError.Number         'Property returns the standard COM error code.

objASPError.Source         'Returns the actual source code, when available, 
                           'of the line that caused the error 

objASPError.Category       'Indicates if the source of the error was internal 
                           'to ASP, the scripting language, or an object 

objASPError.File           'Indicates the name of the .asp file that was being 
                           'processed when the error occurred 

objASPError.Line           'Indicates the line within the .asp file that generated
                           'the error 

objASPError.Column         'Indicates the column position within the .asp file
                           'that generated the error 

objASPError.Description    'Returns a short description of the error 

objASPError.ASPDescription 'Returns a more detailed description of the error 
                           'if it is an ASP-related error 
%>

These are all read-only properties that return variants. Most can be tested against an empty string "" to see if they contain any useful data. For example:

<%
Dim tmp

tmp = objASPError.ASPDescription
If tmp <> "" Then Response.Write(tmp)
%>

Now to take all that data above and use it for something useful. Here's a simple custom error page that writes to a log file. It has two procedures. The first, LogASPError, logs the error information to a log file. The second, GetError, gathers error data from the ASPError object. Together, these two functions gather and record any ASP error that occurs in your pages.

<% @ language="VBScript" %>
<%
option explicit
With response
	.buffer = true
	.clear
	' set the proper http status code (mandatory)
	.status = "500 internal server error"
	.contenttype = "text/html"
	.expires = 0
end With

sub logasperror(byval code, byval num, byval src, byval cat, byval file, _
                byval line, byval column, byval desc, byval adesc)
	' error handling is important because any errors
	' that occur on our new 500-100 custom error 
	' page will be fatal and cause the old, ugly
	' error messages to appear... The chance for error
	' really only lies with the FileSystemObject...
	' so I start handling errors here.

	dim olog, ofile

	on error resume next

	set olog = createobject("scripting.filesystemobject")
	set ofile = olog.opentextfile(server.mappath("/asperrorlog.log"), 8, true)

	' write the error code
	if code <> "" then ofile.write(code & vbtab)

	' using hex on the number property gives it
	' that incomprehensible feel that has always
	' been associated with ASP Error numbers...
	if num <> "" then ofile.write("0x" & hex(num) & vbtab)

	' source is the line of source code that made the error
	if src <> "" then ofile.write(src & vbtab)

	' tells you what threw the error - could be IIS, VBScript or whatever...
	if cat <> "" then ofile.write(cat & vbtab)

	' file is the actual page that crapped out on your site...
	if file <> "" then ofile.write(file & vbtab)

	' line is the line that failed.
	if line <> "" then ofile.write(line & vbtab)

	' column is the character that failed
	if column <> "" then ofile.write(column & vbtab)

	' returns a description of why the code failed, for
	' example: variable not defined 'i'
	if desc <> "" then ofile.write(desc & vbtab)

	' if the error is an asp error, this property has more info for ya.
	if adesc <> "" then ofile.write(adesc & vbtab)

	ofile.write(vbcrlf)

	ofile.close
	set ofile = nothing
	set olog = nothing

	on error goto 0
end sub

sub geterror
	' gather details about the error from the ASPError object

	dim objasperror, code, num, src, cat
	dim line, column, desc, adesc, file

	' get the last error that occurred!
	set objasperror = server.getlasterror

	' go through the properties and get whatever you need...
	With objasperror
		code = .aspcode
		num = .number
		src = .source
		cat = .category
		file = .file
		line = .line
		column = .column
		desc = .description
		adesc = .aspdescription
	end With

	' free ASPError object
	set objasperror = nothing

	' prepare to log error stuff to a file
	logasperror code, num, src, cat, file, line, column, desc, adesc
end sub
%>


<HTML>
<BODY>

<H3>Temporarily unavailable!</H3>

Sorry, we're temporarily updating this page! Please check back soon,
after we have finished updating our content.

<%
' get the error that brought us to this page in the first place
geterror
%>

</BODY>
</HTML>

Okay. After you've written your new error handler page using the ASPError object, you need to install it. In otherwords, you need to tell IIS that it won't be using the default 500-100.asp file, it will use yours instead. Here's how to do it:

  1. Put your new error page somewhere on your web site. Make sure you save it as an ASP file.

  2. Open Internet Services Manager


  3. right click on your HTTP service and select properties


  4. once in the properties screen, click on the "Custom Errors" tab. Then scroll down to the bottom of the list until you get to the 500;100 error. Select it and click the Edit Properties button.


  5. Here is where you declare the path to your new custom error page. First, select a URL message type and then type in the virtual path to your new error handler page.


  6. Now would be a good time to type IISRESET into the command prompt to reset your site, ensuring that the change takes effect immediately.

Now when ASP encounters an error that's not handled in your web site, it will transfer control to your new error page and the ASPError info will be gathered and logged. Since ASP will do a server.transfer to go to your new ASP page, no one will know the path to your error page as their address bar will still be on the page that failed.

Voila, you just learned how to use the seventh built-in ASP object to handle all your error-logging. There's basically no restrictions here at all. Instead of logging the error, you could email it or save it into a database or just print it to the screen. At least now you have some options to disguise ugly error messages.

Download

http://downloads.aspemporium.com/aspError.zip