The PUSH HANDLE and POP HANDLE commands
(COBOL and PL/I only)
The EXEC CICS® PUSH HANDLE command allows you to nest your condition-handling code. For example, when calling a subroutine, you might want a completely different set of EXEC CICS HANDLE CONDITION commands while in the subroutine. (EXEC CICS PUSH HANDLE enables you to suspend all current EXEC CICS HANDLE CONDITION, IGNORE CONDITION, EXEC CICS HANDLE AID, and EXEC CICS HANDLE ABEND commands. This can be useful, for example, during a branch to a subroutine that is embedded in a main program.)
Normally, when a CICS program calls a subroutine, the program that receives control inherits the current HANDLE commands. These commands might not be appropriate within the called program. The called program can use PUSH HANDLE to suspend existing HANDLE commands.
Use PUSH HANDLE therefore, to save your present set of HANDLE commands unchanged while you use a new set in the routine. On exit, you can reinstate the original set of HANDLE commands by using a corresponding POP HANDLE.
* PROCESSING FOR UNEXPECTED ERRORS.
OTHER-ERRORS.
* FIRST, STACK THE CURRENT CONDITION HANDLING
EXEC CICS PUSH HANDLE END-EXEC.
MOVE EIBFN TO ERR-FN, MOVE EIBRCODE TO ERR-RCODE.
MOVE EIBFN TO ERR-COMMAND, MOVE EIBRESP TO ERR-RESP.
MOVE LOW-VALUES TO ACCTERRO.
MOVE EIBTRNID TO TRANEO.
MOVE ERR-PGRMID TO PGMEO.
PERFORM REASON-LOOKUP THROUGH REASON-END
VARYING I FROM 1 BY 1 UNTIL I NOT << IXR.
MOVE ERR-MSG (IXR) TO RSNEO.
IF IXR << 12 MOVE EIBDS TO DSN,
MOVE DSN-MSG TO FILEEO.
PERFORM COMMAND-LOOKUP THROUGH COMMAND-END
VARYING I FROM 1 BY 1 UNTIL I NOT << IXC.
MOVE COMMAND-NAME (IXC) TO CMDEO.
IF ERR-RESP << 94 MOVE RESPVAL (ERR-RESP) TO RESPEO
ELSE MOVE RESPVAL (94) TO RESPEO.
EXEC CICS SEND MAP('ACCTERR') MAPSET('ACCTSET') ERASE EXEC CICS FREEKB
END-EXEC.
EXEC CICS WRITEQ TS QUEUE('ACERLOG') FROM(ACCTERRO)
LENGTH(ERR-LNG) END-EXEC.
* IF CONDITION NOSPACE OCCURS, WAIT FOR TS TO BECOME AVAILABLE
* NOW RESET THE PREVIOUS CONDITION HANDLING
EXEC CICS POP HANDLE END-EXEC.If you choose to include the error lookup and error message display in one of the other programs, you can link to a separate program and arrive at this code from all different points in the code. Note these points:
- EXEC CICS PUSH HANDLE commands can be nested. EXEC CICS PUSH HANDLE suspends the current set of HANDLEs (saving them for later use), and EXEC CICS POP HANDLE restores the set that has most recently been suspended.
- When you link to another program, an EXEC CICS PUSH
HANDLE is implied.
That is, an EXEC CICS PUSH HANDLE occurs between the EXEC CICS LINK command and the first instruction of the linked-to program that begins with the system defaults. It can possibly do some of its own HANDLE, EXEC CICS PUSH HANDLE, or EXEC CICS POP HANDLE commands, but afterward, the stack is popped back to the point at which the EXEC CICS LINK occurred to restore the HANDLE status of the linking program when control is returned there. That is, CICS pushes at each EXEC CICS LINK and pops at each EXEC CICS RETURN.
Note: You cannot use EXEC CICS POP HANDLE on the first command of a linked-to program to reinstate the linked-from program's EXEC CICS HANDLE CONDITIONs. - When you EXEC CICS XCTL to another program, the
current table of conditions, EXEC CICS HANDLE
AID commands, and EXEC CICS ABEND commands (except for
abend handling programs) are cleared, although no implicit EXEC CICS PUSH
HANDLE exists, and you are staying at the same logical program level.
(See How CICS keeps track of what to do.)
One problem with this example is that you do not know where to go at the end of the code, and you do not need such sophistication if you are not going back.
(You could have all your HANDLEs sent to different labels, each of which would consist of PERFORM OTHER-ERRORS, GO TO back, which would be wherever this particular error occurred. This shows some of the limitations of HANDLEs, even with EXEC CICS PUSH HANDLE and EXEC CICS POP HANDLE.)