Overview
The VBScript Err
object provides access to run-time error information.
The Err
object encapsulates errors for a VBScript script. By default, if an error occurs, VBScript terminates script execution and RhinoScript reports the error back to the user. Sometimes this default error processing is not desirable. In this case, the Err
object and the On Error
statement can be used to let scripts perform their own error handling.
Details
The Err
object is a predefined global object. It does not need to be declared before it can be used. The object is used to encapsulate all the information relating to an error condition. This information is presented as a series of properties:
- The
.Number
property is the error number (or code) for the error. This is the default property of the Err object. - The
.Source
property contains a string that specifies the source of the error. This is typically theProgID
(Programmatic Identifier) of the object that generated the error. - The
.Description
property contains a string describing the error. - The
.HelpFile
and.HelpContext
properties store information to reference a help topic in a help file. This allows the error to refer to information on possible causes of the error.
Using On Error
To generate a user-defined run-time error, first clear the Err
object using the .Clear
method. Then raise the error using the .Raise
method. This method takes up to five arguments that correspond, in order, to the properties previously listed. For example:
Err.Clear
Err.Raise 1000, "This is a script-defined error", "Test Script"
This example displays the standard RhinoScript error dialog box showing the error information.
To intercept run-time errors and process them in scripts, use the On Error
statement. The syntax of this statement is:
On Error Resume Next
After this statement executes, the next run-time errors do not cause script execution to end. Instead, the Err
object properties are set to reflect the error information and processing continues with the next statement. For example:
Err.Clear
On Error Resume Next
Err.Raise 100, "Script Error"
If Err.Number Then Rhino.Print "Error=" & CInt(Err.Number)
In this example, the Err.Raise
method is used to raise a run-time error. Normally, this would stop script execution. However, the earlier On Error
statement allows script execution to continue. So the If statement executes and displays the error number.
In the preceding example, the error was generated by the Err.Raise
method. Yet, the same processing applies to any run-time error, regardless of how it is generated. For example:
On Error Resume Next
Err.Clear
x = CInt("foo")
If Err.Number <> 0 Then
Rhino.Print Err.Number
Rhino.Print Err.Description
Rhino.Print Err.Source
End If
Here, an attempt is made to convert the string "foo"
into an integer. Because this is an invalid conversion, a run-time type mismatch error is generated. The information on this error is placed in the Err
object. This is then processed by the If
statement.
After an On Error
statement executes, it remains in effect for the rest of the procedure in which it executes. If the On Error
statement executes in global scope, it remains in effect until the script terminates. Nested procedures can each have their own On Error
statement. For example, subroutine A can execute an On Error
statement and then execute subroutine B, which in turn, executes an On Error
statement.
If an error occurs while an On Error
statement is active, execution continues with the following statement in the same scope as the most recently executed On Error
statement. For example:
On Error Resume Next
Rhino.Print "Begin"
Sub1
Rhino.Print "End"
Sub Sub1
Rhino.Print "Enter Sub1"
Err.Raise 100
Rhino.Print "Leave Sub1"
End Sub
In this example, an On Error
statement executes at global scope, and then the Sub1
procedure executes. Within this procedure, an Err.Raise
method is used to generate an error. Because the most recently executed error is at global scope, the next statement to execute is the Rhino.Print
statement at global scope, and not the Rhino.Print
statement following the Err.Raise
statement. In fact, the error causes VBScript to abandon further execution of the statements in Sub1
and continue execution at global scope. Thus, the output of this script is:
Begin
Enter Sub1
End
Notice that the final Rhino.Print
statement in Sub1
never executes. When an error occurs, VBScript immediately abandons execution of any running procedures necessary to resume with the correct statement after an error. For example:
On Error Resume Next
Rhino.Print "Begin"
Sub1
Rhino.Print "End"
Sub Sub1
Rhino.Print "Enter Sub1"
Sub2
Rhino.Print "Leave Sub1"
End Sub
Sub Sub2
Rhino.Print "Enter Sub2"
Err.Raise 100
Rhino.Print "Leave Sub2"
End Sub
Here, the Err.Raise
method invocation is nested even more deeply. In this case, when the error occurs, VBScript abandons further execution of both Sub1
and Sub2
to continue execution at the global level.
Because VBScript abandons execution of procedures only until it finds the most recently executed On Error
statement, it is possible to capture an error within a procedure simply by placing an On Error
statement in that procedure. For example:
On Error Resume Next
Rhino.Print "Begin"
Sub1
Rhino.Print "End"
Sub Sub1
Rhino.Print "Enter Sub1"
On Error Resume Next
Sub2
Rhino.Print "Leave Sub1"
End Sub
Sub Sub2
Rhino.Print "Enter Sub2"
Err.Raise 100
Rhino.Print "Leave Sub2"
End Sub
This example modifies the previous example by adding an On Error
statement to the Sub1
procedure. So, when the Err.Raise
method in Sub2
executes, execution continues with the next statement in Sub1
. Notice that the Leave Sub2
line never executes. The output from this example is:
Begin
Enter Sub1
Enter Sub2
Leave Sub1
End
Structured Exception Handling
The On Error
statement is a simple form of a technique known as structured exception handling. The basic idea behind this technique is to centralize all the error handling code in a single location outside of the main flow of the program. This is the reason for the complex behavior of the On Error
statement.
The assumption is that a large script might contain many procedures that interact in complex ways. It is possible that an error will occur when procedures are nested very deeply. Without the On Error
statement, each procedure must return some form of error code to the procedure from which it was called. In turn, this procedure must do the same thing, and so on for all the nested procedures. This can greatly add to the complexity of the script.
With the On Error
statement, this complexity can be avoided. When an error occurs, VBScript automatically takes care of unwinding out of the complex nest of procedures back to the statement that followed the original procedure invocation.