About
During execution of the script extension’s services, different errors may occur. For example, the user may specify an incorrect value for a runtime object’s property or a keyword test operation’s parameter, an action may fail to create the checkpoint due to a certain reason, and so on. Script extensions must properly handle such situations.
To handle exceptions that may occur in script extensions, you can use “native” means of the scripting languages that are used to develop extensions -- VBScript and JScript.
In VBScript, you can handle errors using the On Error Resume Next
statement in conjunction with the Err
object. The On Error Resume Next
statement turns error handling on and commands the VBScript engine to continue script execution even if an error occurs. After executing problematic statements, you can check the Err
object to see if any of them raised an error:
VBScript
Sub DoSomething
' Enable exception handling
On Error Resume Next
' Do something
...
' Check if there was an error
If Err.Number <> 0 Then
' Handle the error
' For example, display it to the user:
aqDlg.ShowError Err.Description
' Clear the error indicator
Err.Clear
End If
' Proceed
...
End Sub
In JScript, you can handle exceptions using the try...catch...finally
statement. The try
block contains code that may raise an error, the catch
block -- code that handles the error, the finally
block -- code that is executed regardless of whether or not an exception occurs in the try
block:
JScript
function DoSomething()
{
try
{
// Do something
...
}
catch (e)
{
// Handle the error
// For example, display it to the user:
aqDlg.ShowError(e.description);
}
finally
{
...
}
// Proceed
...
}
For more information about exception handling in VBScript and JScript, refer to the MSDN Library. For example, you can see the description of the On Error
statement and Err
object to learn more about exception handling in VBScript, and the description of the try...catch...finally
statement and Error
object to learn more about exception handling in JScript.
Notifying User About Errors
Besides handling exceptional situations, script extensions should include means to notify a user about occurred errors. The way in which the script extension’s services can do this depends on the service type -- action, object, or keyword test operation.
Record-time and design-time actions can notify a user about errors using the aqDlg.ShowError
or aqDlg.MessageDlg
methods. For example:
JScript
var Result; // Holds the result of the checkpoint creation (success/failure)
...
if (! Result)
aqDlg.ShowError("Failed to create the checkpoint.");
VBScript
Dim Result ' Holds the result of the checkpoint creation (success/failure)
...
If Not Result Then
aqDlg.ShowError "Failed to create the checkpoint."
End If
As for runtime objects, since they are supposed to be used during execution of automated tests, error notifications must be done programmatically, not visually. To illustrate possible solutions, suppose that the script extension provides the SampleObject
runtime object and this object has the Number
property that can hold integer values:
JScript
var number; // An internal variable that holds the Number property value
// The get method of the Number property
function GetNumber()
{
return number;
}
// The set method of the Number property
function SetNumber(Value)
{
number = aqConvert.VarToInt(Value);
}
VBScript
Dim number ' An internal variable that holds the Number property value
' The get method of the Number property
Function GetNumber
GetNumber = number
End Function
' The set method of the Number property
Sub SetNumber(Value)
number = aqConvert.VarToInt(Value)
End Sub
In the set method of the Number
property, we would like to report an error if the specified value cannot be converted into an integer. We can do this in one of the following ways:
-
Use the
Log.Error
orLog.Warning
method to post an error or warning message to the test log. For example:JScript
function SetNumber(Value)
{
try
{
number = aqConvert.VarToInt(Value);
}
catch (e)
{
Log.Error("Unable to set the Number property value.", e.description);
}
}VBScript
Sub SetNumber(Value)
On Error Resume Next
number = aqConvert.VarToInt(Value)
If Err.Number <> 0 Then
Log.Error "Unable to set the Number property value.", Err.Description
End If
End Sub -
Add a special property or method that will return the status of the last method execution. The object’s members should set the status value before returning the control flow to the caller routine. The value 0 can correspond to successful execution, any other value - to error.
The example below illustrates this approach. It extends our sample object with the
LastStatus
property that returns the status code of the last operation performed over the object:JScript
var number;
var last_status; // An internal variable that holds the LastStatus property value
// The set method of the Number property
function SetNumber(Value)
{
try
{
number = aqConvert.VarToInt(Value);
last_status = 0; // The property value has been successfully modified
}
catch (e)
{
last_status = e.number; // An error indicating that Value could not be converted to an integer
}
}
// The Get method of the LastStatus property
function GetLastStatus()
{
return last_status;
}VBScript
Dim last_status ' An internal variable that holds the LastStatus property value
Sub SetNumber(Value)
On Error Resume Next
number = aqConvert.VarToInt(Value)
last_status = Err.Number
' last_status is 0 if Value was successfully converted to an integer.
' Otherwise, last_status contains the error code.
End Sub
' The get method of the LastStatus property
Function GetLastStatus
GetLastStatus = last_status
End FunctionHere is how you can check the object’s
LastStatus
property from test scripts:JavaScript, JScript
function UsingLastStatus()
{
// This line causes an internal error in SampleObject
SampleObject.Number = "not a number";
if (SampleObject.LastStatus != 0)
Log.Error("Unable to set the Number property value");
}Python
def UsingLastStatus(): # This line causes an internal error in SampleObject SampleObject.Number = "not a number" if (SampleObject.LastStatus != 0): Log.Error("Unable to set the Number property value")
VBScript
Sub UsingLastStatus
' This line causes an internal error in SampleObject
SampleObject.Number = "not a number"
If SampleObject.LastStatus <> 0 Then
Log.Error "Unable to set the Number property value"
End If
End SubDelphiScript
procedure UsingLastStatus;
begin
// This line causes an internal error in SampleObject
SampleObject.Number := 'not a number';
if SampleObject.LastStatus <> 0 then
Log.Error('Unable to set the Number property value');
end;C++Script, C#Script
function UsingLastStatus()
{
// This line causes an internal error in SampleObject
SampleObject["Number"] = "not a number";
if (SampleObject["LastStatus"] != 0)
Log["Error"]("Unable to set the Number property value");
} -
Return the status of the object’s method execution via the method’s return value. This approach can only be used by the object’s methods that are not supposed to return other values. It cannot be used in the get and set methods of properties.
To illustrate this approach, suppose that our sample object has the
IncNumber
method that increases the stored number by the specified value. To prevent exceptional situations, this method verifies the type of the passed parameter and returns an error code if the parameter type is invalid (that is, any but integer):JScript
var number;
function IncNumber(Value)
{
var result = 0;
if (aqObject.GetVarType(Value) == varInteger)
number += Value
else
result = 1;
return result;
}VBScript
Dim number
Function IncNumber(Value)
Dim result
result = 0
If (aqObject.GetVarType(Value) = varInteger) Or (aqObject.GetVarType(Value) = varSmallInt) Then
number = number + Value
Else
result = 1
End If
IncNumber = result
End FunctionThe example below demonstrates how you can check the method’s return status in the test code:
JavaScript, JScript
function UsingReturn()
{
SampleObject.Number = 42;
var res = SampleObject.IncNumber(5); // OK, ...
if (res != 0)
Log.Error("Unable to increment the Number property"); // so this line will not be executed
res = SampleObject.IncNumber(true); // The parameter type is incorrect, ...
if (res != 0)
Log.Error("Unable to increment the Number property"); // ... so we'll have this error posted to the log
}Python
def UsingReturn(): SampleObject.Number = 42 res = SampleObject.IncNumber(5) # OK, ... if (res != 0): Log.Error("Unable to increment the Number property") # so this line will not be executed res = SampleObject.IncNumber(True) # The parameter type is incorrect, ... if (res != 0): Log.Error("Unable to increment the Number property") # ... so we'll have this error posted to the log
VBScript
Sub UsingReturn
Dim res
SampleObject.Number = 42
res = SampleObject.IncNumber(5) ' OK, ...
If res <> 0 Then
Log.Error "Unable to increment the Number property" ' ... so this line will not be executed
End If
res = SampleObject.IncNumber(True) ' The parameter type is incorrect, ...
If res <> 0 Then
Log.Error "Unable to increment the Number property" ' ... so we'll have this error posted to the log
End If
End SubDelphiScript
procedure UsingReturn;
var res;
begin
SampleObject.Number := 42;
res := SampleObject.IncNumber(5); // OK, ...
if res <> 0 then
Log.Error('Unable to increment the Number property'); // so this line will not be executed
res := SampleObject.IncNumber(true); // The parameter type is incorrect, ...
if res <> 0 then
Log.Error('Unable to increment the Number property'); // ... so we'll have this error posted to the log
end;C++Script, C#Script
function UsingReturn()
{
SampleObject["Number"] = 42;
var res = SampleObject["IncNumber"](5); // OK, ...
if (res != 0)
Log["Error"]("Unable to increment the Number property"); // so this line will not be executed
res = SampleObject["IncNumber"](true); // The parameter type is incorrect, ...
if (res != 0)
Log["Error"]("Unable to increment the Number property"); // ... so we'll have this error posted to the log
}
Keyword test operations can use a combination of the described approaches. For instance, at design-time they can display errors using the aqDlg.ShowError
or aqDlg.MessageDlg
methods, at run time -- post error messages to the test log using the Log.Error
or Log.Warning
method.
See Also
Script Extensions
Creating Script Extensions
Creating Custom Actions
Creating Runtime Objects
Creating Keyword Test Operations
Debugging Script Extensions