Windows Script Host
This month, I concentrate on a subject that often doesn't receive generic coverage: how you can trap and handle errors in VBScript code that you write for the Windows Script Host (WSH) environment. I discuss three practical ways you can trap and handle errors: explicitly declaring variables, basic error handling with the CheckError subprocedure, and advanced error handling with customized CheckError subprocedures.
Explicitly Declaring Variables
In VBScript, you don't have to explicitly declare the variables that you use. However, explicitly declaring variables is good practice. To make sure that you explicitly declare variables, you can use the Option Explicit command at the beginning of your script. Option Explicit forces the VBScript interpreter (in this case, WSH) to make sure that you use an explicit declaration (i.e., a Dim, Public, or Private statement) to declare a variable before you use it. If you explicitly declare variables and use Option Explicit, you'll spend less time debugging scripts because you'll immediately catch such errors as misspelled variable names and mismatched variables.
If your script has many variables and you put each explicit declaration on a separate line, your script can get long. To save space, you can take advantage of VBScript's vastly underused colon (:) to join two lines of code. For more information about this space saver, see the sidebar "Taking Advantage of VBScript's Colon," page 2.
Basic Error Handling
The CheckError subprocedure in Listing 1, page 2, lets you trap and handle runtime errors in any script. Here's how CheckError works. First, the subprocedure declares the strMessage variable. This variable will eventually contain a text string that provides information about an error if an error occurs. To determine whether an error has occurred, CheckError uses an If...Then...Else statement that draws on VBScript's Err object. (Because the Err object has a global scope, you don't have to instantiate this object before you use it.) The Err object's default property is Err::Number, so when the If...Then...Else statement checks whether Err = 0, it's actually checking whether Err.Number = 0. When no error occurs, Err.Number returns the value of 0; when an error occurs, Err.Number returns a nonzero integer that represents the type of error that occurred. So, if Err = 0, the subprocedure exits because no error has occurred. If Err is any other number, the subprocedure continues to the next line.
In the next line, CheckError uses the Err::Source, Err::Number (i.e., Err), and Err::Description properties to obtain data about the error and store that data in strMessage. Err::Source returns data about the error's sourcethat is, the class name or programmatic identifier (ProgID) of the object or application that caused the error. As I just explained, Err::Number returns data about the type of error that occurred. Err::Description returns a short description of the object or application that caused the error.
CheckError then prints the text string that strMessage contains. Finally, the subprocedure uses the WScript::Quit command to quit the script and returns an error code of 1 to indicate that an error occurred.
CheckError quits the script if an error occurs. If you want the script to continue executing after an error occurs, you can modify CheckError. Replace the line
WScript.Quit 1
with
Err.Clear
Then when an error occurs, CheckError will print a message, reset the Err object to 0, and wait for another error while the script continues to execute.
CheckError isn't a script in and of itself. Thus, to use it, you need to perform three steps:
- Add the subprocedure in Listing 1 to the end of the script in which you want to check for errors.
- At the beginning of the script, add the line
On Error Resume Next
As Listing 2 shows, you can place this statement after the Option Explicit command. The On Error Resume Next statement enables WSH to trap errors with the Err object. On Error Resume Next prompts WSH to reset the Err object's properties to 0 or zero-length strings ("").
- At the point in which you want to use CheckError in your script, add the line
CheckError
to invoke the subprocedure. As callout A in Listing 2 shows, instead of specifying CheckError on a separate line, you can use a colon to append this command to the applicable line.