You use the SET command to give $ETRAP the value of a string that contains one or more ObjectScript commands. Then, when an error occurs, Caché executes the commands you entered into $ETRAP. For example, suppose you set $ETRAP to a string that contains a GOTO command to transfer control to an error-handling routine:
Caché then executes this command in $ETRAP immediately following any ObjectScript command that generates an error condition. Caché executes the $ETRAP command at the same context level in which the error condition occurs. Caché saves the $ROLES value in effect when $ETRAP is set; when the $ETRAP code is executed, Caché sets $ROLES to that saved value. This prevents the $ETRAP error handler from using elevated privileges that were granted to the routine after establishing the error handler.
When setting $ETRAP to execute an error handler (for example, with a GOTO command) you can specify the error handler as label (a label in the current routine), ^routine (the beginning of a specified external routine), or label^routine (a specified label in a specified external routine).
$ETRAP supports label+offset in some contexts (but not in procedures). This optional +offset is an integer specifying the number of lines to offset from label. InterSystems recommends that you avoid the use of a line offset when specifying an error handler location.
The maximum length of a SET $ETRAP string is 32,741 characters. Setting $ETRAP to a longer string may result in a <MAXSTRING> error.
The commands in a $ETRAP string are not executed in a new context level, unlike the commands in an XECUTE string. In addition, the $ETRAP command string is always terminated by an implicit QUIT command. The implicit QUIT command quits with a null-string argument when the $ETRAP error-handling commands are invoked in a user-defined function context where an argumented QUIT command is required.
By default, Caché carries the value of the $ETRAP special variable forward into new DO, XECUTE, and user-defined function contexts. However, you can create a new copy of $ETRAP in a context by issuing the NEW command, as follows:
Whenever you issue a NEW for $ETRAP, Caché performs the following actions:
Saves the copy of $ETRAP that was in use at that point.
The following example demonstrates how the value of $ETRAP is carried forward into new contexts and how you can invoke $ETRAP error-handling commands again in each context after an error occurs. The $ETRAP commands in this example make no attempt to dismiss the error. Rather, control by default is passed back to $ETRAP error-handling commands at each previous context level.
The sample code is as follows:
ETRNEW$ETRAPSET$ETRAP="WRITE !,""$ETRAP invoked at Context Level "",$STACK"; Initiate an XECUTE context that initiates a DO contextXECUTE"DO A"QUIT; Initiate a user-defined function contextASETA=$$BQUIT; A User-defined function that generates an errorB()QUIT1
A sample session using this code might run as follows:
$ETRAP invoked at context level 4
$ETRAP invoked at context level 3
$ETRAP invoked at context level 2
$ETRAP invoked at context level 1
If you assign a new value to $ETRAP in a context without first creating a new copy of $ETRAP with the NEW command, Caché establishes that new value as the value of $ETRAP not only for the current context but also for all previous contexts. Therefore, InterSystems strongly recommends that you use the NEW $ETRAP command to create a new copy of $ETRAP before you set $ETRAP with a new value.
Because the string value of $ETRAP is executable ObjectScript commands, the length of the string cannot be longer than the maximum length of an ObjectScript routine line. See Using Caché ObjectScript for more information.
When you set an error handler using $ZTRAP, this handler takes precedence over any existing $ETRAP error handler. Caché implicitly performs a NEW $ETRAP command and sets $ETRAP to the null string ("").
$ETRAP and TRY / CATCH
The TRY and CATCH commands perform error handling within an execution level. When an exception occurs within a TRY block, Caché normally executes the CATCH block of exception handler code that immediately follows the TRY block.
Use of $ETRAP within a program structured with TRY blocks is strongly discouraged.
You cannot set $ETRAP within a TRY block. Attempting to do so generates a compilation error. You can set $ETRAP prior to the TRY block, or within the CATCH block.
If $ETRAP was previously set and an exception occurs in a TRY block, Caché may take $ETRAP rather than CATCH unless you forestall this possibility. If both $ETRAP and CATCH are present when an exception occurs, Caché executes the error code (CATCH or $ETRAP) that applies to the current execution level. Because $ETRAP is intrinsically not associated with an execution level, Caché assumes that it is associated with the current execution level unless you specify otherwise. You must NEW $ETRAP before setting $ETRAP to establish a level marker for $ETRAP, so that Caché will correctly take CATCH as the current level exception handler, rather than $ETRAP. Otherwise, a system error (including a system error thrown by the THROW command) may take the $ETRAP exception handler.
An exception that occurs within a CATCH block is handled by the current error trap handler.