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.ErrororLog.Warningmethod 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 LastStatusproperty 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 LastStatusproperty 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 IncNumbermethod 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 logVBScript 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
