CICS Event Handlers

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.

Explain Like I'm Five: What Are Event Handlers?

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.

HANDLE CONDITION: Handling Command Conditions

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.

Common conditions for HANDLE CONDITION
ConditionMeaningWhen
NOTFNDResource or record not foundREAD, DELETE, etc.
DUPREC / DUPKEYDuplicate keyWRITE to keyed file
INVREQInvalid request (wrong state or parameter)Various commands
LENGERRLength errorBuffer too small or wrong length
MAPFAILNo data received from terminalRECEIVE MAP
ERRORUnhandled condition; often leads to abendCondition not in HANDLE CONDITION
cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
EXEC 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.

HANDLE AID: Handling Attention Identifiers

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.

Common AIDs for HANDLE AID
AIDMeaningTypical use
ENTEREnter keySubmit form or confirm
CLEARClear keyReset screen or cancel
PF1 .. PF24Program function keysMenu options, help, etc.
PA1 .. PA3Program attention keysAlternate actions
ANYKEYAny key not explicitly handledCatch-all for unknown keys
cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
EXEC 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.

Interaction: HANDLE AID vs HANDLE CONDITION

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 ...).

PUSH HANDLE and POP HANDLE

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.

cobol
1
2
3
4
5
6
7
8
*> 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

NOHANDLE: In-Line Response Checking

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.

Step-by-Step: Setting Up Condition Handlers

  1. Identify the conditions that can occur on the EXEC CICS commands you will use (e.g. NOTFND on READ, DUPREC on WRITE, MAPFAIL on RECEIVE MAP).
  2. Issue EXEC CICS HANDLE CONDITION condition1(para1) condition2(para2) ... END-EXEC early in the program (e.g. right after entry).
  3. Code each paragraph to handle that condition: set messages, return, retry, or log and abend. Ensure the paragraph does not cause an infinite loop (e.g. retry only with a limit or after changing input).
  4. Optionally add HANDLE CONDITION ERROR(error-para) to catch any unhandled condition and perform a last-resort cleanup or message.

Step-by-Step: Handling PF Keys and CLEAR

  1. Decide which keys your map supports (e.g. Enter to submit, PF3 to exit, CLEAR to reset).
  2. Issue EXEC CICS HANDLE AID ENTER(process-para) PF3(exit-para) CLEAR(clear-para) [ANYKEY(unknown-para)] END-EXEC before the RECEIVE that will get the key.
  3. After SEND MAP, execute RECEIVE MAP. When the user presses a key, CICS branches to the matching paragraph. In that paragraph, process the action (e.g. validate and update for Enter, return to menu for PF3).
  4. If you use ANYKEY, the unknown-key paragraph runs for any key you did not list; use it to display "Invalid key" or similar.

Best Practices

  • Handle all conditions you expect (NOTFND, DUPREC, MAPFAIL, etc.) so the task does not abend for normal cases.
  • In condition paragraphs, do not perform the same failing command again without changing data or state, to avoid loops.
  • Use HANDLE AID for every key your map documents (Enter, PF3, etc.) and ANYKEY for a clear message when an unsupported key is pressed.
  • Use PUSH HANDLE before linking to a program that sets its own handlers, and POP HANDLE after return so the caller's handlers are restored.
  • When using NOHANDLE, always check EIBRESP (or RESP) immediately after the command and branch; do not assume NORMAL.

Test Your Knowledge

Test Your Knowledge

1. When NOTFND occurs and you have HANDLE CONDITION NOTFND(NOT-FOUND-PARA), CICS:

  • Abends
  • Transfers control to NOT-FOUND-PARA
  • Ignores it
  • Retries the READ

2. HANDLE AID is used to:

  • Handle file errors
  • Handle the key the user pressed (e.g. PF3, CLEAR)
  • Handle NOTFND
  • Handle DB2

3. To save current handlers and set new ones temporarily you use:

  • HANDLE CONDITION only
  • PUSH HANDLE then set new handlers; POP HANDLE to restore
  • NOHANDLE only
  • RELEASE HANDLE