CICS event handlers let your program react to two kinds of events: command conditions (e.g. NOTFND, DUPREC) and user attention keys (e.g. Enter, PF3, CLEAR). You use HANDLE CONDITION to branch to a paragraph when a condition occurs, and HANDLE AID to branch when the user presses a specific key. PUSH HANDLE and POP HANDLE let you save and restore handlers so subroutines can install their own without losing yours. This page explains how to use these commands and how they interact.
Imagine CICS as a receptionist. When something happens—a file read says "not found," or the user presses the Help key—the receptionist can either do the default thing (often "panic" and stop) or follow your instructions: "If you get 'not found,' go to this paragraph;" "If the user presses PF3, go to that paragraph." Event handlers are those instructions. You tell CICS in advance what to do when certain events happen so your program can handle them calmly instead of abending or ignoring the key.
EXEC CICS HANDLE CONDITION lets you name one or more conditions and the paragraph (or section label) to which CICS should transfer control when that condition occurs. The command applies to the program in which it is issued and affects subsequent EXEC CICS commands in that program until the program returns or you push/pop or override the handler. When a command (e.g. READ FILE) returns a condition such as NOTFND, CICS does not take the default action (often an abend); instead it branches to the paragraph you specified. You can list multiple conditions in one HANDLE CONDITION (e.g. NOTFND, DUPREC, INVREQ), each with its own paragraph. A later HANDLE CONDITION for the same condition replaces the previous one. Typically you issue HANDLE CONDITION once near the start of the program so all subsequent commands in that program use those handlers.
| Condition | Meaning | When |
|---|---|---|
| NOTFND | Resource or record not found | READ, DELETE, etc. |
| DUPREC / DUPKEY | Duplicate key | WRITE to keyed file |
| INVREQ | Invalid request (wrong state or parameter) | Various commands |
| LENGERR | Length error | Buffer too small or wrong length |
| MAPFAIL | No data received from terminal | RECEIVE MAP |
| ERROR | Unhandled condition; often leads to abend | Condition not in HANDLE CONDITION |
12345678910111213141516EXEC CICS HANDLE CONDITION NOTFND(RECORD-NOT-FOUND) DUPREC(DUPLICATE-RECORD) MAPFAIL(NO-INPUT-RECEIVED) END-EXEC EXEC CICS READ FILE('CUSTFILE') RIDFLD(WS-KEY) INTO(WS-REC) END-EXEC *> If record not found, control goes to RECORD-NOT-FOUND RECORD-NOT-FOUND. MOVE 'Customer not found' TO WS-MESSAGE EXEC CICS SEND MAP(...) END-EXEC EXEC CICS RETURN END-EXEC.
In the condition paragraph, handle the error (set a message, return to the menu, retry, or log and abend). Avoid performing logic that can cause the same condition again without changing state, or you may get an infinite loop. If you do not handle a condition and the default is to abend, CICS may raise ERROR; you can HANDLE CONDITION ERROR(error-para) to catch any unhandled condition and log or clean up before exiting.
When the user presses a key on the terminal (Enter, a PF key, CLEAR, etc.), that key is sent as an attention identifier (AID). EXEC CICS HANDLE AID lets you associate a paragraph with specific AIDs. When you do a RECEIVE (e.g. RECEIVE MAP) and the data from the terminal includes that AID, CICS branches to the paragraph you specified instead of continuing in line. So you can have one paragraph for Enter (process the form), another for PF3 (exit or cancel), another for CLEAR (reset). HANDLE AID takes precedence over HANDLE CONDITION for that receive. You can use ANYKEY to handle any AID that you did not list explicitly; useful for "unknown key pressed, show message." The handler remains active until the program ends or you issue another HANDLE AID for the same AID. If you use RESP or NOHANDLE on the RECEIVE command, the normal HANDLE AID behavior can be suspended so you can check the AID in your code (e.g. from the EIB) and branch yourself.
| AID | Meaning | Typical use |
|---|---|---|
| ENTER | Enter key | Submit form or confirm |
| CLEAR | Clear key | Reset screen or cancel |
| PF1 .. PF24 | Program function keys | Menu options, help, etc. |
| PA1 .. PA3 | Program attention keys | Alternate actions |
| ANYKEY | Any key not explicitly handled | Catch-all for unknown keys |
1234567891011121314EXEC CICS HANDLE AID ENTER(PROCESS-FORM) PF3(EXIT-TO-MENU) CLEAR(RESET-SCREEN) ANYKEY(UNKNOWN-KEY) END-EXEC EXEC CICS RECEIVE MAP('MENUMAP') MAPSET('MENUMAP') END-EXEC *> Control already transferred to PROCESS-FORM, EXIT-TO-MENU, etc. *> So we only get here if no AID matched (e.g. if ANYKEY not used) PROCESS-FORM. *> Validate and process input EXEC CICS RETURN END-EXEC.
The order of HANDLE AID and RECEIVE matters: set HANDLE AID before the RECEIVE that will get the key. After RECEIVE, if an AID matched, you are already in the handler paragraph; the data from the map is still available so you can read field values there.
HANDLE AID has precedence over HANDLE CONDITION for the same receive. When the user presses a key, CICS first checks HANDLE AID; if the key is listed, it branches there. If not (and no ANYKEY), it may then consider conditions (e.g. MAPFAIL if no data). Using RESP and RESP2 on a command stores the response in your variables; using NOHANDLE disables automatic branching for that command so you must check EIBRESP (or your RESP variable) and branch yourself. That is useful when you want to handle several outcomes in one place (e.g. IF EIBRESP = NOTFND ... ELSE IF EIBRESP = NORMAL ...).
EXEC CICS PUSH HANDLE saves the current HANDLE CONDITION and HANDLE AID settings and then clears them. After that you can issue new HANDLE CONDITION and HANDLE AID commands (e.g. in a subroutine or for a specific phase). EXEC CICS POP HANDLE restores the handlers that were in effect at the last PUSH. So you can nest: main program sets handlers, PUSH HANDLE, linked program sets its own handlers, does work, returns, main does POP HANDLE and has its handlers back. If you PUSH multiple times, each POP restores the previous level. Use PUSH/POP when you call code that needs different handlers without losing the caller's handlers, or when you want to temporarily disable all handlers and use NOHANDLE and in-line checks.
12345678*> Main program handlers EXEC CICS HANDLE CONDITION NOTFND(NOT-FOUND) END-EXEC EXEC CICS PUSH HANDLE END-EXEC *> Handlers are now cleared EXEC CICS LINK PROGRAM('SUB1') COMMAREA(WS-AREA) END-EXEC EXEC CICS POP HANDLE END-EXEC *> NOTFND(NOT-FOUND) is active again
When you add NOHANDLE to an EXEC CICS command, CICS does not transfer control to a HANDLE CONDITION or HANDLE AID paragraph for that command. The command completes (or sets a condition), and execution continues to the next statement. You must then check EIBRESP (or the variable you specified in RESP) and branch based on the value. This gives you explicit, in-line control: IF EIBRESP = DFHRESP(NOTFND) PERFORM NOT-FOUND ELSE IF EIBRESP = DFHRESP(NORMAL) ... Use NOHANDLE when you want to handle several responses in one place or when you prefer not to use condition paragraphs. Mixing HANDLE CONDITION and NOHANDLE in the same program is valid: only the commands with NOHANDLE skip the handler.
1. When NOTFND occurs and you have HANDLE CONDITION NOTFND(NOT-FOUND-PARA), CICS:
2. HANDLE AID is used to:
3. To save current handlers and set new ones temporarily you use: