Easy Error Management

aspTired of hunting down mysterious bugs which users have reported (perhaps incorrectly) within your application? Having a problem with VBScript’s IsNumeric() function? These few tricks will serve to make your application more user-friendly, but more importantly help you prevent, locate, and fix errors even if no one reports the bug!

Contributed by
Rating: 5 stars5 stars5 stars5 stars5 stars / 30
December 08, 2003
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement
Chances are, if you are reading this article, you plan to script or have scripted one or more ASP application(s). To follow this stating-the-obvious form of logic, it can be safely stated that you will run into some of the very same problems that I have, which will more or less occur as follows:

[italic]You:
I have created the ultimate ASP application!!!

User: I found a bug!

You:
1. Where did you find it?
2. What was the error message?
3. What were you doing?

User:
1. I don’t know.
2. I don’t remember exactly what the message was, something like ‘type mismatch’…I think.
3. I was just (with one of the following): logging on/off; saving/generating a report; I don’t remember, etc…

You:
oh.[/italic]

This is followed by hours of you trying to mimic the actions of the user, within their permission level, performing countless actions within the application, all in hopes of finding the mysterious bug. You throw in countless lines of “Response.Write( variable & “ - “ & TypeName( variable ) )“ to locate the offending variable.

Upon determining the cause of the error, and the cause of the cause, you realize some degree of error-checking is necessary. The following three tricks will speed up the debugging of you applications, save you many, many lines of code, and are easily reusable.

First Trick: Checking for Truly Numeric Values

VBScript has many built-in functions to verify data types, such as IsEmpty(), IsDate(), and so forth. One issue you may encounter in your ASP application involves the IsNumeric() function. This is because VBScript evaluates Hex numbers, numbers in scientific notation, numbers with double notation, and currency all as numeric. This could be a problem because you have coded expecting only whole integers, no d’s, no e’s, and definitely no $’s. So we are therefore called upon to be a little more specific, and this can be accomplished with the following function:


'===================================================
Function isTrulyNumeric( intToCheck ) 
'
===================================================
intToCheck TrimintToCheck )
If 
LenintToCheck ) = OR IsEmptyintToCheck Then
        isTrulyNumeric 
False
     
Else
        
Dim ci
        isTrulyNumeric 
True
        
For 1 To LenintToCheck )
            
AscMidintToChecki) )
            If 
<= 44 OR 57 OR 47 Then 
                isTrulyNumeric 
False 
                
Exit For 
            
End If 
        
Next 
    End 
If
    
End Function


Explanation: This function iterates through each character in the given parameter ( intToCheck ), checking them against their ASCII value. The only permitted characters are 0-9, ‘.’, and ‘-‘ (for negatives).

Using this function and VBScript’s other functions, along with some careful planning and analyzing of where you need which data types, will save you endless frustration and the headaches that generally accompany it!

Second Trick: User-Friendly Error Reporting

The second trick involves two steps. The first step is the oh-so-vital “friendly” error message. This is a necessity because, generally speaking, when one sees “Microsoft VBScript runtime error,” there is no obvious plan of action associated with it, leaving both the user and programmer stranded. The second step, admittedly an optional one, is to take the responsibility of reporting the error off of the user, by having the error emailed to you, tracked in a database, or both.

Step 1 - Placate the User

So, we have to stop users from being scared off by ASP’s inherent, and somewhat cryptic, error messages. This can be accomplished with some soothing color, and a calming explanation of what on earth is wrong. Take a look at the following:


'=========================================================
Sub errorMessage( strMSG ) 
'
=========================================================
    
dim blOptionalInfo    
    
    blOptionalInfo 
false 
=== you can hard-code to true/false, or have it depending on permissions
    
    
Response
.Write"<div align=""left"" style=""font: 10pt verdana, arial;margin: 25px;")
    
Response.Write"padding:1em;background-color:#E6EAF7; border: 1px solid #BDCFDE"">")
    
Response.Write"<h3>You have encountered an error!</h3>" )
    
Response.WritestrMSG )
    
If 
blOptionalInfo Then
 Response
.Write"<p><b>Debug Info:</b>
)
     
Response.Write"URL: " Request.ServerVariables("URL") & "
)
     
Response.Write"QUERY_STRING: " Request.ServerVariables("QUERY_STRING") & "
)
     
Response.Write"RU: " Request.ServerVariables("REMOTE_USER") & "
)
     
Response.Write"RA: " Request.ServerVariables("REMOTE_ADDR") & "
)
End if

    
Response.WriteNow() )
    
Response.Write"<p><a href=""javascript:history.back()"">Go back</a>
"
)
    
Response.Write"<a href=""/"">Home</a>" )
    
Response.Write"</div>" )
    
Response.End()
End Sub


Explanation: Here we are telling the user in plain English what has just happened, where they are, how they got there, and where to go from here. Here’s an example:


If Not isTrulyNumericintUserID Then
    Call errorMessage
("The user id you have supplied is invalid! (“ & intUserID & “)” )
 Else
    ‘proceed
End If


This method of reporting will make your programming life much easier and your users happier, guaranteed or your money back!

Step 2 - Obtaining Omniscience

Imagine you were the one contacting a user about an error they encountered, not vice versa. Imagine that not only were you able to explain the error quickly, but also explain that you’ve already fixed it! Imagine the enormous amounts of trust and respect (not to mention $$) that would be heaped upon you!

This is fairly easy to accomplish. All you need to do, is create another subprocedure for emailing/logging the error, and call it from the errorMessage() subprocedure. You’ll want to modify the code below with the all variants you wish to be tracked.


'=========================================================
Sub reportError( strMSG ) 
'
=========================================================
    
dim arVarsobjMailstrBodyi
    
    redim arVars
# of items to track )
arVars) = “error:” strMSG
arVars
) = “time:” now()
arVars) = “user id:” intUserID
arVars
) = “page:” Request.ServerVariables("URL")
arVars) = “querystring:” Request.QueryString()
arVars) = “form data:” Request.Form()
arVars# ) = etc…

set objMail     Server.CreateObject(“CDONTS.NewMail”)
objMail.To      “youremail@domain.com”
objMail
.Subject “error report”

strBody 
“the following error was encountered” vbCrLf vbCrLf

For 0 To UBoundarVars )
    
strBody strBody arVars) & vbCrLf
Next

objMail
.Body strBody
objMail
.Send()

Set objMail Nothing
arVars 
Null

‘followed by optional tracking in a database
 
End Sub


So there you have it! With good planning, you can be made aware of 99% of all the errors that occur within your application, without depending on the user to notify you. Lastly, let’s just look at one handy trick to save time with our debugging.

Third Trick: The Quick Debugger

If you’re at all like me, you will quickly be annoyed by typing and re-typing the same lines of code to read your offending variables, their type, size, and so forth. So, it’s always handy to have a subprocedure do all the work for you. Here’s a simple one:


'=========================================================
Sub debug( var )
'
=========================================================
    
Response.Write("<span style=""font-size: 9pt;font-family: arial; font-weight: normal"">")
    
Response.Write("<strong>Type = " typeName( var ) & "
"
)
    If 
Not typeName( var ) = "Variant()" Then 
        Response
.Write"Size = " len(var) & "
)
        
Response.Write"<u>Value</u></strong>
)
Response.WriteReplace( var, vbCrLf"
"
) )
     Else
         
Dim intDimsij
        intDims 
CountDims( var )
        if 
intDims 3 then
            
For 0 to UBound( var, )
                If 
intDims 1 then
                     Response
.Write("var( " " ): " )
Response.Writetypename( var( ) ) & " = " )
Response.Write( var( ) & "
vbCrLf )
 Else
                    For 
0 to UBound( var, )    
                        
Response.Write("var( " ", " " ): " )
Response.Writetypename( var( i) ) & " = " )
Response.Write( var( i) & "
vbCrLf )
                    
Next
    
                End 
If
            
Next
          
Else
            
Response.Write“array has “ intDims “ dimensions.” )    
        
End If
    
End If
    
Response.Write("</span>")
    
Response.End()
End Sub


For this to work on arrays, you’ll need the function below. Currently the debugger works with up to two dimensions, but could be modified to do more if that’s necessary within your application.


<script language="JScript" runat="server">
    function 
CountDimsarrVBArray ) {
        return 
arrVBArray.dimensions();
    }
</script>


Basically, you could use the subprocedure debug() anywhere you want to see what a variable is in gory detail. What I have started doing is inserting it - commented out - in places where I could foresee errors occurring, such as when picking up Query String elements, or with SQL SELECT statements. Example:


Dim intUserIDstrSQL
intUserID 
TrimRequest.QueryString(“intUserID”) )
‘debugintUserID )

strSQL “SELECT FROM users WHERE id “ intUserID
‘debug
strSQL )


This way, when I need to do some quick debugging, I simply un-comment the desired line, and I’m well on my way to finding the cause of the error.

Conclusion

I hope you find these techniques as useful as I have. I can honestly say that using this method of error reporting has saved me hours of frustrated searching. I also believe that using the debugger has prevented carpal tunnel syndrome brought on by typing millions of Response.Write()- Response.End()’s.
blog comments powered by Disqus
ASP ARTICLES

- Using MySQL with ASP
- ADO for the Beginner
- ADO.NET 101: Data Rendering with a DataGrid ...
- Introducing SoftArtisans OfficeWriter 3.0 En...
- Getting Remote Files With ASP
- The Real Basics of Functions in ASP
- Enhancing Readability with ASP
- Mimicking PHP's String Formatting Functions
- Windows Server Hacks 12, 77, and 98
- How to Sort a Multi-Dimensional Array
- Developing an Information Management Tool wi...
- What are Active Server Pages?
- Getting Remote Pages with ASP
- FTP’ing Files with ASP
- Apply Single-Sign-On to Your Application

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
 
 
 

ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 7 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials