Summary: Discusses the VBScript Err object.
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 however, 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.
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, as follows:
To generate a user-defined run-time error, first clear the Err object using the .Clear method, and 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, subsequent run-time errors do not cause script execution to terminate. 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 terminate script execution. However, the earlier On Error statement allows script execution to continue, and so the If statement executes and displays the error number.
In the preceding example, the error was generated by the Err.Raise method. However, 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, and this is then processed by the If statement.
After an On Error statement executes, it remains in effect for the remainder 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 whatever running procedures are necessary in order 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 in order 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. Thus, 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
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 apparently 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 add greatly 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 following the original procedure invocation.