Terminating Execution on an Error

If both $ETRAP and $ZTRAP are set to the empty string upon encountering an error, the current level is discarded and the error is reissued at the invoking level. When already at the lowest M stack level, GT.M terminates routine execution and returns control to the DCL level. If $ZTRAP is used exclusively, $ZTRAP="" suppresses the unstacking of NEWed values of $ZTRAP associated with lower levels. $ETRAP values are always unstacked, however if the lowest level $ETRAP is the empty string (which it is by default when GT.M starts), GT.M performs the same termination as it does with $ZTRAP. These terminations with both ISVs empty provides a mechanism for returning to DCL with a status message when GT.M encounters an error.

Example:

	GTM>ZPRINT ^EP7
	EP7WRITE !,"THIS IS ",$TEXT(+0)
	SET $ECODE="";this only affects $ETRAP
	SET $ETRAP="",$ZTRAP=""
	KILL A
	BADWRITE A
	WRITE !,"THIS IS NOT DISPLAYED"
	QUIT
	
	GTM>DO ^EP7
	
	THIS IS EP7
	%GTM-E-UNDEF, Undefined local variable: A
	%GTM_I-RTSLOC,At M source location BAD^EP7
	
	$ WRITE SYS$OUTPUT $STATUS
	%X08F685DA
	
	
	

GT.M issues a message describing the M error and releases control to the invoking DCL. If your application packages M invocations in DCL, the DCL can determine the nature of the exit by examining the VMS symbol $STATUS.

When the action specified by $ZTRAP results in another run-time error before changing the value of $ZTRAP, the routine may iteratively invoke $ZTRAP until a stack overflow terminates the GT.M image. SETting $ZTRAP="" at the beginning of error processing ensures that this type of infinite loop does not occur. Because $ETRAP is implicitly followed by a QUIT it does not have the tendency to recurse. While $ETRAP is resistant to recursion, it is not completely immune, because a GOTO or a ZGOTO within the same level can evade the implicit QUIT. $ETRAP error handling involving errors on more than one stack level can also be induced to recurse if $ECODE is inappropriately cleared before the errors at all levels have been properly dealt with.

Example:

		GTM>ZPRINT ^EP8
		EP8WRITE !,"THIS IS ",$TEXT(+0)
		NEW $ZTRAP SET $ZTRAP="DO ET"
		KILL A
		BADWRITE A
		WRITE !,"THIS IS NOT DISPLAYED"
		QUIT
		ETWRITE 2/0
		QUIT
		
		GTM>DO ^EP8
		
		THIS IS EP8
		%GTM-E-STACKCRIT, Stack space critical
		%GTM-E-ERRWZTRAP, Error while processing $ZTRAP
		
		$
	

When the routine encounters an error at label BAD, GT.M transfers control to label ET. When the routine encounters an error at label ET, it recursively does ET until a stack overflow condition terminates the GT.M image.

A set $ZTRAP="" command as soon as the program enters an error-handling routine prevents this type of "infinite" recursion.

	GTM>ZPRINT ^EP8A
	EP8AWRITE !,"THIS IS ",$TEXT(+0)
	SET $ECODE=""
	SET $ZTRAP="",$ETRAP="DO ET"
	KILL A
	BADWRITE A
	WRITE !,"THIS IS NOT DISPLAYED"
	QUIT
	ETWRITE !,"CONTINUING WITH ERROR TRAP AFTER AN ERROR"
	ZSHOW "S"
	WRITE !,"HERE COMES AN ERROR IN THE TRAP CODE"
	WRITE 2/0
	QUIT
	
	GTM>DO ^EP8A
	
	THIS IS EP8A
	CONTINUING WITH ERROR TRAP AFTER AN ERROR ET+1^EP8A
	Indirection ($ZTRAP)
	+1^GTM$DMOD (Direct mode)
	
	HERE COMES AN ERROR IN THE TRAP CODE
	GTM>
	

This demonstrates how $ETRAP behavior in this circumstance is more appropriate. Note that the $ZTRAP="" at the lowest level, prevents exection from returning to Direct Mode when the initial value of $ZTRAP ("B") is unstacked; this step takes $ZTRAP out of the equation and should be part of initialization when the intention is to use $ETRAP exclusively.

Example:

	GTM>ZPRINT ^EP9
	EP9WRITE !,"THIS IS ",$TEXT(+0)
	SET $ZTRAP="DO ET"
	KILL A
	BADWRITE A
	WRITE !,"THIS IS NOT DISPLAYED"
	QUIT
	ETSET $ZT=""
	WRITE !,"THIS IS THE ERROR TRAP"
	ERRORWRITE !,"HERE COMES AN ERROR IN THE ERROR TRAP"
	WRITE 2/0
	QUIT
	
	GTM>DO ^EP9
	
	THIS IS EP9
	THIS IS THE ERROR TRAP
	HERE COMES AN ERROR IN THE ERROR TRAP
	%GTM-E-LABELMISSING, Label referenced but not defined: ET
	%GTM_E-ERRWETRAP, Error while processing $ETRAP
	
	%GTM-E-DIVZERO, Attempt to divide by zero
	$
	
	
	

This routine sets the value of $ZTRAP to null as soon as the program enters the error handler. This insures program termination when an error occurs in the error handler.