HANDLE CONDITION — abordagem legada

HANDLE CONDITION é a abordagem original do CICS para tratar erros — anterior à introdução do RESP. Funciona como um GO TO implícito: quando ocorre uma condição de exceção em qualquer comando EXEC CICS, o controle salta para o parágrafo especificado.

       PROCEDURE DIVISION.

       INICIO.
           * registrar handlers — válidos para toda a tarefa daqui em diante
           EXEC CICS HANDLE CONDITION
                          NOTFND(CONTA-NAO-ENCONTRADA)
                          DUPKEY(CHAVE-DUPLICADA)
                          LENGERR(ERRO-TAMANHO)
                          ERROR(ERRO-GENERICO)
           END-EXEC

           EXEC CICS READ FILE('CNTFILE')
                          INTO(WS-CONTA)
                          RIDFLD(WS-CHAVE)
                          LENGTH(WS-LENGTH)
           END-EXEC
           * se NOTFND: controle vai para CONTA-NAO-ENCONTRADA
           * se OK: continua aqui
           PERFORM PROCESSAR-CONTA.

       CONTA-NAO-ENCONTRADA.
           MOVE 'CONTA INEXISTENTE' TO MENSAGEMO
           PERFORM ENVIAR-MENSAGEM.
⚠️ HANDLE CONDITION é considerado legado. O problema é que o handler vale para todos os comandos EXEC CICS a partir do ponto onde foi declarado — não só para o próximo. Isso cria fluxo de controle não-linear difícil de ler e manter. Em código novo, use sempre RESP.

Para cancelar um handler registrado, use HANDLE CONDITION NOTFND sem label (desativa) ou IGNORE CONDITION NOTFND (ignora silenciosamente a condição):

* desativar o handler de NOTFND
           EXEC CICS HANDLE CONDITION
                          NOTFND
           END-EXEC

* ignorar NOTFND completamente (execução continua normalmente)
           EXEC CICS IGNORE CONDITION NOTFND END-EXEC

RESP e RESP2 — abordagem moderna

Com RESP, cada comando EXEC CICS recebe um parâmetro RESP(variável). O CICS coloca nessa variável o código de resposta da operação. O programa verifica imediatamente depois e toma a ação adequada — sem saltos implícitos.

       WORKING-STORAGE SECTION.
       01  WS-RESP          PIC S9(8) COMP.
       01  WS-RESP2         PIC S9(8) COMP.

       PROCEDURE DIVISION.

           EXEC CICS READ FILE('CNTFILE')
                          INTO(WS-CONTA)
                          RIDFLD(WS-CHAVE)
                          LENGTH(WS-LENGTH)
                          RESP(WS-RESP)
                          RESP2(WS-RESP2)
           END-EXEC

           EVALUATE WS-RESP
               WHEN DFHRESP(NORMAL)
                   PERFORM PROCESSAR-CONTA
               WHEN DFHRESP(NOTFND)
                   MOVE 'CONTA NAO ENCONTRADA' TO MENSAGEMO
                   PERFORM ENVIAR-MENSAGEM
               WHEN DFHRESP(DISABLED)
                   MOVE 'ARQUIVO INDISPONIVEL' TO MENSAGEMO
                   PERFORM ENVIAR-MENSAGEM
               WHEN OTHER
                   PERFORM TRATAR-ERRO-INESPERADO
           END-EVALUATE.
CampoTipoConteúdo
RESPPIC S9(8) COMPCódigo principal — compare com DFHRESP(nome-da-condição)
RESP2PIC S9(8) COMPCódigo secundário — detalha o motivo dentro da condição RESP. Valor documentado por condição na referência CICS.
Sempre use DFHRESP(nome) para comparar, nunca compare o número bruto. Os valores numéricos são internos e podem mudar entre versões do CICS. DFHRESP(NORMAL) vale 0, mas escreva sempre o nome simbólico.

Condições de exceção mais comuns

CondiçãoQuando ocorreComandos que podem gerar
NORMALOperação concluída com sucessoTodos
NOTFNDRegistro não encontradoREAD, READNEXT, READPREV, DELETE
DUPKEYChave duplicada no WRITEWRITE (arquivo com KSDS sem UNIQ)
DUPRECRegistro com RBA duplicadoWRITE em ESDS
ENDFILEFim de arquivo no browseREADNEXT, READPREV
DISABLEDArquivo fechado ou desabilitado no CICSREAD, WRITE, BROWSE...
FILENOTFOUNDNome de arquivo não definido no CSDQualquer comando FILE()
LENGERRTamanho do registro diferente do esperadoREAD, READNEXT, RECEIVE
MAPFAILRECEIVE MAP sem dados do terminalRECEIVE MAP
PGMIDERRPrograma não definido ou não encontradoLINK, XCTL
TRANSIDERRTRANSID inválidoSTART, RETURN TRANSID()
QIDERRFila TS ou TD não encontradaREADQ TS/TD, DELETEQ TS
ITEMERRNúmero de item inválido na fila TSREADQ TS, WRITEQ TS REWRITE
NOTAUTHUsuário sem autorização RACFQualquer comando com resource-level security
INVREQRequisição inválida — opção incompatívelVários — detalhado no RESP2
SYSIDERRSistema remoto inacessível (MRO/ISC)Comandos com SYSID()

HANDLE ABEND — interceptando ABENDs

HANDLE ABEND registra um parágrafo para ser executado quando a tarefa CICS sofre um abend. Diferente do HANDLE CONDITION (que trata erros de comandos EXEC CICS específicos), o HANDLE ABEND captura qualquer abend — inclusive erros de programa como divisão por zero (ASRA) ou loop infinito (AICA).

       PROCEDURE DIVISION.

       INICIO.
           EXEC CICS HANDLE ABEND
                          LABEL(ROTINA-ABEND)
           END-EXEC

           PERFORM PROCESSAR-TRANSACAO
           EXEC CICS RETURN TRANSID(EIBTRNID)
                            COMMAREA(WS-COMMAREA) END-EXEC.

       ROTINA-ABEND.
           * essa rotina é invocada pelo CICS antes do cleanup do abend
           * aqui você pode: gravar log, exibir mensagem, fazer SYNCPOINT ROLLBACK

           EXEC CICS ASSIGN ABCODE(WS-ABEND-CODE) END-EXEC
           MOVE WS-ABEND-CODE TO WS-LOG-ABCODE

           * gravar log do abend na fila TD
           EXEC CICS WRITEQ TD
                          QUEUE('ALOG')
                          FROM(WS-LOG-RECORD)
                          LENGTH(LENGTH OF WS-LOG-RECORD)
           END-EXEC

           * exibir mensagem amigável ao usuário
           MOVE 'ERRO INTERNO - CONTATE O SUPORTE' TO MENSAGEMO
           EXEC CICS SEND MAP('MAPERRO')
                          MAPSET('BANCMAP1')
                          FROM(MAPERRO)
                          ERASE
           END-EXEC

           * deixar o CICS fazer o cleanup normal do abend
           EXEC CICS ABEND ABCODE('APPL') END-EXEC.
⚠️ A rotina de HANDLE ABEND não pode fazer EXEC CICS RETURN. Ela deve terminar com EXEC CICS ABEND (para propagar o abend e forçar o cleanup do CICS) ou EXEC CICS XCTL (para transferir controle para outra transação). Se a rotina cair em STOP RUN ou em outro abend sem handler, o resultado é imprevisível.

Cancelando o handler

* desativar o handler de abend
           EXEC CICS HANDLE ABEND CANCEL END-EXEC

* reativar com novo label
           EXEC CICS HANDLE ABEND LABEL(NOVA-ROTINA) END-EXEC

Códigos de ABEND mais comuns

Códigos de abend CICS têm 4 caracteres. Os que começam com A são gerados pelo próprio CICS; os que começam com outras letras ou dígitos são definidos pela aplicação (com EXEC CICS ABEND ABCODE('XYZW')).

CódigoNomeCausaComo investigar
ASRA Program Check Erro de programa: divisão por zero, referência a campo não inicializado, overflow aritmético, endereço inválido Analisar o dump — o PSW (Program Status Word) aponta a instrução que causou o erro. No COBOL, mapear o offset do dump para a linha do listing
AICA Runaway Task Loop infinito — a tarefa consumiu CPU além do ICVR (Runaway Interval Control Value), tipicamente 2 segundos de CPU contínua Verificar loops PERFORM com condição que nunca se torna falsa; verificar cursores DB2 abertos sem FETCH em loop
AKCP Deadlock Timeout Deadlock entre tarefas — a tarefa esperou por um recurso além do DTIMOUT (deadlock timeout) Verificar ordem de acesso a arquivos VSAM e tabelas DB2; usar CEMT INQUIRE TASK para ver quais tasks estão esperando
APCT Program Not Found Programa chamado por LINK ou XCTL não existe no CICS (não definido no CSD ou load library) Verificar definição do programa no CSD com CEDA DISPLAY PROGRAM; verificar se o load module está na STEPLIB do CICS
ATNI Terminal Not Intelligent Comando de tela (SEND MAP, RECEIVE MAP) enviado para terminal que não suporta BMS Verificar definição do terminal no CSD — TERMTYPE deve ser compatível com BMS
AEYH Not Authorized Usuário sem autorização RACF para executar a transação ou acessar o recurso Verificar perfil RACF do usuário; usar CICS Security para inspecionar autorizações
ASRB OS Abend in Program Abend do sistema operacional (S0C4, S0C7...) dentro de um programa CICS Como ASRA — analisar dump; o código OS está no campo ABCODE do EIB
AEY9 Invalid EXEC CICS Command Comando EXEC CICS inválido em tempo de execução — parâmetro incompatível ou fora de contexto Verificar RESP2 se capturado; analisar o comando que gerou o abend no dump
🦕 ASRA é o mais frequente em ambiente de desenvolvimento. Geralmente causado por: campo numérico com conteúdo não-numérico (MOVE de campo X para campo 9 sem validação), ponteiro não inicializado, ou overflow em operação COMPUTE. O dump mostra exatamente qual instrução assembler falhou — mapeie o offset para a linha COBOL no listing do compilador.

DUMP TRANSACTION — solicitando diagnóstico

EXEC CICS DUMP TRANSACTION solicita ao CICS que grave um dump da tarefa atual no dataset de dump (DFHDMPA ou DFHDMPB). É útil quando você detecta uma condição de erro e quer capturar o estado completo da memória para diagnóstico posterior.

       TRATAR-ERRO-CRITICO.
           * capturar informações antes do dump
           EXEC CICS ASSIGN
                          ABCODE(WS-ABCODE)
                          TASK(WS-TASK-NUMBER)
                          USERID(WS-USERID)
           END-EXEC

           * solicitar dump com título identificador
           EXEC CICS DUMP TRANSACTION
                          DUMPCODE('ERRC')         * código de 4 chars para identificar
                          COMPLETE                 * dump completo, incluindo núcleo do CICS
                          RESP(WS-RESP)
           END-EXEC

           * prosseguir com o tratamento de erro
           EXEC CICS SYNCPOINT ROLLBACK END-EXEC
           MOVE 'ERRO CRITICO REGISTRADO' TO MENSAGEMO
           PERFORM ENVIAR-MENSAGEM.
ParâmetroSignificado
DUMPCODE(4 chars)Código identificador para localizar o dump no dataset depois
COMPLETEInclui áreas do núcleo CICS além da tarefa — dump maior mas mais completo
SEGMENTLIST / FROM / LENGTHAlternativamente, especifica qual área de memória incluir no dump
Dumps são volumosos e impactam performance — não use em fluxo normal. Use apenas em rotinas de tratamento de erro para condições inesperadas. Em ambiente de produção, o número de dumps é limitado pela configuração CICS (MAXDUMPS) para evitar esgotamento de espaço.

ASSIGN — inspecionando o ambiente da tarefa

EXEC CICS ASSIGN recupera informações sobre a tarefa CICS em execução: usuário, terminal, transação, número da tarefa, versão do CICS e outros atributos do ambiente. É muito usado em rotinas de log e de tratamento de erros.

       WORKING-STORAGE SECTION.
       01  WS-ENV.
           05  WS-USERID        PIC X(8).
           05  WS-TERMID        PIC X(4).
           05  WS-TRANSID       PIC X(4).
           05  WS-TASK-NUM      PIC S9(7) COMP-3.
           05  WS-ABCODE        PIC X(4).
           05  WS-CICS-VER      PIC X(4).
           05  WS-SYSID         PIC X(4).

       PROCEDURE DIVISION.

       CAPTURAR-CONTEXTO.
           EXEC CICS ASSIGN
                          USERID(WS-USERID)
                          TERMCODE(WS-TERMID)
                          TCTUALENG(WS-TRANSID)
                          TASKN(WS-TASK-NUM)
                          ABCODE(WS-ABCODE)
                          SYSID(WS-SYSID)
                          RESP(WS-RESP)
           END-EXEC.
Opção ASSIGNO que retorna
USERIDID do usuário RACF da tarefa (8 chars)
TERMCODE / TERMINALID do terminal onde a tarefa está rodando
TASKNNúmero único da tarefa CICS (útil para correlacionar logs)
ABCODECódigo do abend em curso (válido dentro do handler de abend)
SYSIDID do sistema CICS local (4 chars)
APPLIDID da aplicação VTAM do CICS
STARTCODEComo a tarefa foi iniciada: TD (trigger), D (direto), S (START), U (usuário)
OPIDID do operador (3 chars) — definido no perfil RACF

CEDF — depurador interativo

O CEDF (CICS Execution Diagnostic Facility) é o depurador do CICS. Ele intercepta cada comando EXEC CICS antes e depois da execução, permitindo inspecionar parâmetros, alterar valores e controlar o fluxo — tudo em tempo real na tela 3270.

Como ativar o CEDF

Opção 1: digitar CEDF no terminal antes de iniciar a transação
  CEDF      ← tecle ENTER
  resposta: "THIS TERMINAL: EDF MODE ON"
  CNTA      ← agora inicie sua transação normalmente

Opção 2: ativar de outro terminal (para monitorar transações iniciadas por START)
  CEDF T002  ← ativa EDF no terminal T002 a partir do terminal atual

O que o CEDF mostra

Para cada comando EXEC CICS, o CEDF para a execução e exibe uma tela com:

  STATUS: ABOUT TO EXECUTE COMMAND
  ─────────────────────────────────────────────────────────────────
  EXEC CICS READ
            FILE        ('CNTFILE')
            INTO        (address: 00A1B2C0)
            RIDFLD      ('0001234567')
            LENGTH      (200)
  ─────────────────────────────────────────────────────────────────
  OFFSET: X'00001234'  LINE: 0089  EIBFN: X'0602'
  ─────────────────────────────────────────────────────────────────
  PF1=HELP  PF3=END EDF  PF4=SUPPRESS  PF5=WORK AREA  PF6=USER DISP
  PF7=SCROLL BACK  PF8=SCROLL FWD  PF9=MSG SUPP  PF10=PREV DISP
  ENTER=CONTINUE
TeclaAção no CEDF
ENTERExecuta o comando e para na próxima interceptação
PF4Supprime a exibição para os próximos N comandos (útil para pular laços)
PF5Exibe a Working-Storage do programa (browse de memória)
PF6Exibe a tela do usuário como está no momento
PF3Desativa o CEDF para a tarefa atual
PF9Suprime mensagens do CEDF (execução mais rápida)
CEDF é a primeira ferramenta a usar quando um programa se comporta de forma inesperada. Você vê exatamente quais parâmetros estão sendo passados para cada comando EXEC CICS e qual RESP é retornado — sem precisar alterar o código.
⚠️ Nunca deixe CEDF ativo em produção. Além de impactar performance, qualquer erro no terminal com CEDF ativo trava a tarefa aguardando interação — o que pode congelar transações do usuário por tempo indefinido.

CECI e CECS — testando comandos CICS

CECI (CICS Execution Command Interpreter) permite executar comandos EXEC CICS interativamente — sem precisar escrever um programa. Ideal para testar se um arquivo está acessível, ler registros, verificar filas TS e explorar o ambiente.

* acessar CECI
CECI                        ← tela de entrada do CECI

* exemplos de comandos no CECI
CECI READ FILE('CNTFILE') RIDFLD('0001234567') INTO(?)
CECI READQ TS QUEUE('T001LIST') ITEM(1) INTO(?)
CECI WRITEQ TS QUEUE('TESTE123') FROM('TESTE DE FILA') LENGTH(14)
CECI DELETEQ TS QUEUE('TESTE123')
CECI INQUIRE FILE('CNTFILE')   ← verifica status do arquivo

CECS (CICS Execution Command Syntax checker) valida a sintaxe de um comando EXEC CICS sem executá-lo — útil para verificar se os parâmetros estão corretos antes de criar o programa.

* verificar sintaxe no CECS
CECS READ FILE('CNTFILE') RIDFLD(?) INTO(?) LENGTH(?)
* resposta: "COMMAND SYNTAX IS CORRECT" ou lista os erros
💗 CECI na prática: Imagine que você precisa verificar se o arquivo CNTFILE está ativo antes de reportar um problema. Em vez de criar um job batch ou program de teste, basta abrir o terminal, digitar CECI e executar CECI INQUIRE FILE('CNTFILE') — o CICS mostra status, OPENSTATUS, ENABLESTATUS e outras propriedades em segundos.

Padrão robusto de tratamento de erros

A abordagem mais sólida em programas CICS de produção combina: RESP em cada comando, HANDLE ABEND global para capturar o inesperado, e uma rotina centralizada de log de erros.

       WORKING-STORAGE SECTION.
       01  WS-RESP              PIC S9(8) COMP.
       01  WS-RESP2             PIC S9(8) COMP.
       01  WS-LOG-ERRO.
           05  WS-LOG-TRANSID   PIC X(4).
           05  WS-LOG-USERID    PIC X(8).
           05  WS-LOG-TERMINAL  PIC X(4).
           05  WS-LOG-PONTO     PIC X(20).
           05  WS-LOG-RESP      PIC S9(8) COMP.
           05  WS-LOG-RESP2     PIC S9(8) COMP.
           05  WS-LOG-SQLCODE   PIC S9(9) COMP.

       PROCEDURE DIVISION.

       INICIO.
           * registrar handler de abend global
           EXEC CICS HANDLE ABEND LABEL(ROTINA-ABEND) END-EXEC

           IF EIBCALEN = 0
               MOVE 'I' TO WS-FASE
           ELSE
               MOVE DFHCOMMAREA TO WS-COMMAREA
           END-IF

           PERFORM DESPACHAR-FLUXO
           EXEC CICS RETURN TRANSID(EIBTRNID)
                            COMMAREA(WS-COMMAREA)
                            LENGTH(LENGTH OF WS-COMMAREA)
           END-EXEC.

       DESPACHAR-FLUXO.
           EVALUATE TRUE
               WHEN WS-FASE = 'I'  PERFORM TELA-ENTRADA
               WHEN WS-FASE = 'P'  PERFORM PROCESSAR
               WHEN OTHER            PERFORM TELA-ENTRADA
           END-EVALUATE.

       PROCESSAR.
           EXEC CICS READ FILE('CNTFILE')
                          INTO(WS-CONTA)
                          RIDFLD(WS-CHAVE)
                          LENGTH(WS-LENGTH)
                          RESP(WS-RESP)
                          RESP2(WS-RESP2)
           END-EXEC

           EVALUATE WS-RESP
               WHEN DFHRESP(NORMAL)
                   PERFORM CONTINUAR-PROCESSAMENTO
               WHEN DFHRESP(NOTFND)
                   MOVE 'CONTA NAO ENCONTRADA' TO MENSAGEMO
                   PERFORM ENVIAR-MENSAGEM
               WHEN OTHER
                   MOVE 'LEITURA DE CONTA' TO WS-LOG-PONTO
                   PERFORM REGISTRAR-ERRO-INESPERADO
           END-EVALUATE.

       REGISTRAR-ERRO-INESPERADO.
           * capturar contexto
           EXEC CICS ASSIGN
                          USERID(WS-LOG-USERID)
                          RESP(WS-RESP)
           END-EXEC
           MOVE EIBTRNID    TO WS-LOG-TRANSID
           MOVE EIBTRMID    TO WS-LOG-TERMINAL
           MOVE WS-RESP     TO WS-LOG-RESP
           MOVE WS-RESP2    TO WS-LOG-RESP2
           MOVE SQLCODE     TO WS-LOG-SQLCODE

           * gravar na fila de log
           EXEC CICS WRITEQ TD
                          QUEUE('ALOG')
                          FROM(WS-LOG-ERRO)
                          LENGTH(LENGTH OF WS-LOG-ERRO)
                          RESP(WS-RESP)
           END-EXEC

           * desfazer a UOW
           EXEC CICS SYNCPOINT ROLLBACK RESP(WS-RESP) END-EXEC

           * mensagem ao usuário
           MOVE 'ERRO INTERNO - OPERACAO CANCELADA' TO MENSAGEMO
           PERFORM ENVIAR-MENSAGEM.

       ROTINA-ABEND.
           * capturar código do abend
           EXEC CICS ASSIGN
                          ABCODE(WS-ABCODE)
                          USERID(WS-LOG-USERID)
                          RESP(WS-RESP)
           END-EXEC
           MOVE EIBTRNID TO WS-LOG-TRANSID
           MOVE EIBTRMID TO WS-LOG-TERMINAL
           MOVE 'ABEND ' TO WS-LOG-PONTO(1:6)
           MOVE WS-ABCODE TO WS-LOG-PONTO(8:4)

           EXEC CICS WRITEQ TD
                          QUEUE('ALOG')
                          FROM(WS-LOG-ERRO)
                          LENGTH(LENGTH OF WS-LOG-ERRO)
                          RESP(WS-RESP)
           END-EXEC

           * propagar o abend para o CICS fazer o cleanup
           EXEC CICS ABEND ABCODE(WS-ABCODE) END-EXEC.
🟣 Avançado — EIB como fonte de diagnóstico: O bloco EIB (Execute Interface Block) contém campos valiosos para diagnóstico imediatamente após um erro: EIBFN (função do último comando EXEC CICS executado, em hex), EIBRCODE (reason code detalhado, 6 bytes), EIBRSRCE (nome do recurso envolvido, 8 chars) e EIBRECV (indicator de recebimento de dados). Em qualquer rotina de diagnóstico, esses campos devem ser gravados antes de qualquer outro comando EXEC CICS, pois o próximo comando os sobrescreve.