Chapter 16 Quiz: Declaratives and Exception Handling

Test your understanding of COBOL error handling mechanisms. Each question is followed by a hidden answer -- try to answer before revealing it.


Question 1

Where in the PROCEDURE DIVISION must the DECLARATIVES section appear?

Show Answer The DECLARATIVES section must appear **immediately after the PROCEDURE DIVISION header**, before any other sections or paragraphs. No executable code can precede DECLARATIVES. The section begins with the keyword DECLARATIVES and ends with END DECLARATIVES, both on their own lines.
       PROCEDURE DIVISION.
       DECLARATIVES.
       ...
       END DECLARATIVES.
       MAIN-LOGIC SECTION.

Question 2

What keyword is required in a USE statement to associate a declarative procedure with a file I/O error?

a) USE ON ERROR b) USE AFTER STANDARD ERROR PROCEDURE ON c) USE BEFORE ERROR ON d) USE EXCEPTION HANDLER FOR

Show Answer **b) USE AFTER STANDARD ERROR PROCEDURE ON**. The full syntax is:
       ERROR-SECTION SECTION.
           USE AFTER STANDARD ERROR PROCEDURE ON file-name.
The word STANDARD is optional in most compilers, but including it is best practice for clarity. The USE statement can specify a file name, or one of the generic categories: INPUT, OUTPUT, I-O, or EXTEND.

Question 3

True or False: A single DECLARATIVES section can contain multiple USE statements, each in its own SECTION, to handle errors on different files.

Show Answer **True**. The DECLARATIVES block can contain as many sections as needed. Each section has its own USE AFTER ERROR statement specifying which file (or file category) triggers that handler:
       DECLARATIVES.
       INPUT-ERR SECTION.
           USE AFTER STANDARD ERROR PROCEDURE ON INPUT-FILE.
       INPUT-ERR-PARA.
           ...
       OUTPUT-ERR SECTION.
           USE AFTER STANDARD ERROR PROCEDURE ON OUTPUT-FILE.
       OUTPUT-ERR-PARA.
           ...
       END DECLARATIVES.
Each USE statement must be in its own SECTION. You cannot have two USE statements in the same section.

Question 4

What file status code indicates a successful I/O operation?

Show Answer **00** (zero-zero). A file status of 00 means the I/O operation completed without any error or exceptional condition. The file status field is a PIC XX (two-character alphanumeric) field defined in WORKING-STORAGE and associated with the file through the FILE STATUS clause in the SELECT statement.

Question 5

What is the file status code for end-of-file when reading a sequential file?

Show Answer **10**. File status 10 indicates that a READ statement attempted to read beyond the last record in the file. This is the normal termination condition for sequential file processing and is NOT an error -- it simply means there are no more records to read. This condition triggers the AT END phrase if one is coded on the READ statement.

Question 6

Which file status code indicates "record not found" when reading an indexed file by key?

a) 10 b) 22 c) 23 d) 35

Show Answer **c) 23**. File status 23 means the record with the specified key does not exist in the file. This occurs on READ, START, or DELETE operations when the key value does not match any record in the indexed file. This condition triggers the INVALID KEY phrase if one is coded. Status 10 is end-of-file on sequential read. Status 22 is duplicate key on write. Status 35 is file not found on OPEN.

Question 7

True or False: If both a DECLARATIVES error procedure and an INVALID KEY phrase are coded for the same file, the DECLARATIVES procedure is executed first.

Show Answer **False**. When both a DECLARATIVES procedure and an inline exception phrase (INVALID KEY, AT END) are coded, the **inline phrase takes precedence** and the declarative procedure is **not** invoked. The declarative procedure is only invoked when no inline exception phrase is coded on the failing statement. This is an important design consideration: if you want centralized error handling through DECLARATIVES, do not code inline exception phrases on individual I/O statements for the same file.

Question 8

What happens if an I/O error occurs and neither a DECLARATIVES procedure nor an inline exception phrase (AT END, INVALID KEY) is coded?

Show Answer The program **abends** (abnormal end). Without any error-handling mechanism, the runtime system treats I/O errors as unrecoverable and terminates the program. On z/OS, this typically produces an abend code (such as U4038 for COBOL runtime errors) and a system dump. This is why defensive programming practices require either file status checking, inline exception phrases, or DECLARATIVES for every file operation.

Question 9

What is the purpose of the FILE STATUS clause in a SELECT statement?

Show Answer The FILE STATUS clause designates a WORKING-STORAGE variable (PIC XX) that the runtime system automatically updates after **every** I/O operation on that file. This allows the program to check the result of each operation without relying solely on DECLARATIVES or inline exception phrases.
       SELECT CUSTOMER-FILE ASSIGN TO CUSTMAST
           FILE STATUS IS WS-CUST-STATUS.
Best practice is to define FILE STATUS on **every** file in the program. The two-character status code provides specific information about what happened: 00 for success, 10 for end-of-file, 23 for record not found, 35 for file not found, and so on.

Question 10

What does file status code 35 indicate?

Show Answer File status **35** indicates that an OPEN statement failed because the **file does not exist** (and the file is not defined as OPTIONAL). On z/OS, this typically means the DD statement in the JCL is missing or the dataset specified does not exist. On GnuCOBOL, it means the file path does not point to an existing file. To allow a program to handle missing files gracefully, define the file as OPTIONAL in the SELECT statement:
       SELECT OPTIONAL HISTORY-FILE ASSIGN TO HISTFILE
           FILE STATUS IS WS-HIST-STATUS.
With OPTIONAL, opening a non-existent input file returns status 05 instead of 35, and the first READ returns status 10 (end-of-file).

Question 11

Which of the following statements support the ON SIZE ERROR phrase? (Select all that apply)

a) ADD b) READ c) COMPUTE d) DIVIDE e) WRITE f) MULTIPLY g) SUBTRACT h) MOVE

Show Answer **a) ADD, c) COMPUTE, d) DIVIDE, f) MULTIPLY, g) SUBTRACT**. The ON SIZE ERROR phrase applies to all arithmetic statements. It is triggered when the result of an arithmetic operation is too large to fit in the receiving field, or when a division by zero occurs. READ uses AT END and INVALID KEY. WRITE uses INVALID KEY (for indexed files). MOVE does not have any exception phrase -- it silently truncates.

Question 12

What is the difference between ON SIZE ERROR behavior when the phrase IS coded versus when it is NOT coded?

Show Answer When ON SIZE ERROR **is coded**: The receiving field is **not modified** (it retains its previous value), and the imperative statements in the ON SIZE ERROR phrase are executed. When ON SIZE ERROR **is not coded**: The result is **undefined**. The receiving field may contain a truncated value, zero, or garbage depending on the compiler and platform. The program continues execution without any warning. This is dangerous because incorrect financial calculations will proceed silently. This is why ON SIZE ERROR should be coded on every arithmetic operation in financial programs.

Question 13

True or False: The AT END phrase on a READ statement is triggered for both sequential and random READ operations.

Show Answer **False**. The AT END phrase is triggered only on **sequential** READ operations (ACCESS MODE IS SEQUENTIAL or sequential reads in DYNAMIC mode using READ ... NEXT). For random READ operations (ACCESS MODE IS RANDOM or random reads using a key), the **INVALID KEY** phrase is used instead, with file status 23 indicating the record was not found.

Question 14

What scope terminator ends the inline error handling for a READ statement?

Show Answer **END-READ**. Every inline exception phrase should be terminated with the corresponding END-verb scope terminator: | Statement | Scope Terminator | |-----------|-----------------| | READ ... AT END | END-READ | | WRITE ... INVALID KEY | END-WRITE | | REWRITE ... INVALID KEY | END-REWRITE | | DELETE ... INVALID KEY | END-DELETE | | START ... INVALID KEY | END-START | | COMPUTE ... ON SIZE ERROR | END-COMPUTE | | ADD ... ON SIZE ERROR | END-ADD | | DIVIDE ... ON SIZE ERROR | END-DIVIDE | Omitting scope terminators in COBOL-85 and later is a common source of logic errors, especially with nested IF statements.

Question 15

A programmer codes the following. What is wrong, and what will happen at runtime?

           OPEN INPUT CUSTOMER-FILE
           IF WS-CUST-STATUS NOT = '00'
               DISPLAY 'OPEN FAILED'
               STOP RUN
           END-IF

But the SELECT statement is:

           SELECT CUSTOMER-FILE ASSIGN TO CUSTMAST.
Show Answer The SELECT statement is **missing the FILE STATUS clause**. Without `FILE STATUS IS WS-CUST-STATUS`, the runtime system does not populate WS-CUST-STATUS after the OPEN. The field WS-CUST-STATUS will contain whatever value it had before the OPEN (its initial value or spaces), making the IF test meaningless. The corrected SELECT should be:
           SELECT CUSTOMER-FILE ASSIGN TO CUSTMAST
               FILE STATUS IS WS-CUST-STATUS.
This is one of the most common errors in COBOL error handling: checking a file status field that is not connected to the file through the FILE STATUS clause.

Question 16

What is the purpose of the NOT INVALID KEY phrase?

Show Answer The **NOT INVALID KEY** phrase specifies statements to execute when the I/O operation completes **successfully** (no key error). It is the "happy path" counterpart to INVALID KEY:
           READ MASTER-FILE INTO WS-MASTER-REC
               INVALID KEY
                   PERFORM 9100-RECORD-NOT-FOUND
               NOT INVALID KEY
                   PERFORM 2200-PROCESS-RECORD
           END-READ
This provides a clean structure for separating success and error processing without needing a separate IF statement after the READ. The NOT INVALID KEY phrase was introduced in COBOL-85 along with other "NOT" exception phrases (NOT AT END, NOT ON SIZE ERROR, NOT ON OVERFLOW).

Question 17

What file status codes fall in the "logic error" category (status codes beginning with 4)?

Show Answer Status codes beginning with **4** indicate logic errors -- the programmer has done something invalid in the sequence of I/O operations: | Code | Meaning | |------|---------| | 41 | OPEN attempted on a file that is already open | | 42 | CLOSE attempted on a file that is not open | | 43 | DELETE or REWRITE without a prior successful READ (for sequential access) | | 44 | Record length violation -- record written is outside the range specified in the FD | | 46 | Sequential READ attempted without establishing position (no prior READ, START, or OPEN) | | 47 | READ attempted on a file not opened for INPUT or I-O | | 48 | WRITE attempted on a file not opened for OUTPUT, I-O, or EXTEND | | 49 | DELETE or REWRITE attempted on a file not opened for I-O | These are bugs in the program logic, not runtime errors. They should never occur in a correctly coded program.

Question 18

In a USE AFTER ERROR statement, can you specify a file category instead of a specific file name? If so, what categories are available?

Show Answer **Yes**. Instead of naming a specific file, you can use one of four file categories: - **INPUT** -- handles errors on all files opened for input - **OUTPUT** -- handles errors on all files opened for output - **I-O** -- handles errors on all files opened for I-O (update) - **EXTEND** -- handles errors on all files opened for extend
       ALL-INPUT-ERRORS SECTION.
           USE AFTER STANDARD ERROR PROCEDURE ON INPUT.
       ALL-INPUT-HANDLER.
           DISPLAY 'ERROR ON AN INPUT FILE'
           .
If both a file-specific handler and a category handler exist, the **file-specific handler** takes precedence. A file cannot be covered by two category handlers. You cannot have both a file-specific and a category handler triggered for the same error.

Question 19

What is the difference between file status 22 and file status 02?

Show Answer Both relate to duplicate keys, but they have very different meanings: - **Status 22**: A WRITE or REWRITE operation attempted to create a record with a **primary key** value that already exists, OR a duplicate value in an **alternate key** that does not allow duplicates. The operation **fails** and the record is NOT written. - **Status 02**: A READ or WRITE operation succeeded, but the key involved has a **duplicate** value in an alternate key that DOES allow duplicates. The operation **succeeds**. Status 02 is informational, indicating that other records exist with the same alternate key value. In financial systems, status 22 (rejected duplicate) and status 02 (accepted duplicate) require different handling. Ignoring status 02 is usually fine; ignoring status 22 means losing transactions.

Question 20

True or False: The ON OVERFLOW phrase on a STRING statement works the same way as ON SIZE ERROR on arithmetic statements.

Show Answer **True** in terms of behavior pattern: when the overflow condition occurs, the receiving field is left in its **current state** (partially filled) and the ON OVERFLOW imperative statements execute. If ON OVERFLOW is not coded, the operation terminates silently and the program continues with a partially filled receiving field. The overflow condition for STRING occurs when the POINTER value exceeds the length of the receiving field, meaning there is not enough room to concatenate all the source strings. For UNSTRING, ON OVERFLOW triggers when there are more delimited substrings than receiving fields.
           STRING WS-FIRST-NAME DELIMITED SPACE
                  ' '            DELIMITED SIZE
                  WS-LAST-NAME   DELIMITED SPACE
               INTO WS-FULL-NAME
               WITH POINTER WS-PTR
               ON OVERFLOW
                   DISPLAY 'NAME TRUNCATED'
           END-STRING

Question 21

What IBM abend code is commonly associated with a data exception (attempting to perform arithmetic on non-numeric data)?

Show Answer **S0C7** (System 0C7). This is the most common abend in COBOL programming. It occurs when a packed decimal or zoned decimal field contains non-numeric data (invalid characters, spaces, or low-values) and the program attempts an arithmetic operation, comparison, or MOVE on it. Common causes: - Uninitialized WORKING-STORAGE fields (contain spaces instead of zeros) - Reading a record into the wrong record layout - Group MOVE that overlays a numeric field with alphanumeric data - Missing or incorrect INITIALIZE statement - Input data that was not validated before arithmetic use The fix is always to validate numeric fields before using them in arithmetic and to initialize all WORKING-STORAGE fields properly.

Question 22

A program opens a VSAM file and gets file status 93. What does this typically indicate, and what should the program do?

Show Answer File status **93** is an IBM-specific status code meaning the **VSAM resource is not available**. This typically occurs when: 1. Another job or CICS region has the file allocated exclusively 2. The file is being backed up or reorganized 3. A CICS region holds the file open and the batch job cannot share it The program should: 1. Log the error with the file name and status code 2. If this is a known contention situation (e.g., batch window overlap), implement retry logic with a delay 3. If retries are exhausted, terminate gracefully with a clear error message indicating which file is locked and suggesting when to retry 4. Notify operations or scheduling so the job can be rescheduled after the conflicting job completes
           OPEN I-O ACCOUNT-FILE
           IF WS-ACCT-STATUS = '93'
               DISPLAY 'ACCOUNT FILE LOCKED BY ANOTHER JOB'
               DISPLAY 'RETRY AFTER CURRENT JOB COMPLETES'
               MOVE 16 TO RETURN-CODE
               STOP RUN
           END-IF

Question 23

Explain the relationship between DECLARATIVES, file status codes, and inline exception phrases. If all three are coded for the same file, which takes effect?

Show Answer The precedence order is: 1. **Inline exception phrases** (AT END, INVALID KEY, etc.) take highest precedence. If an inline phrase is coded on the I/O statement, it handles the error and the DECLARATIVES procedure is **not** invoked. 2. **DECLARATIVES** procedure fires only when no inline exception phrase is coded on the failing statement. 3. **File status** is always updated, regardless of whether DECLARATIVES or inline phrases are coded. It is updated **before** either handler executes. The recommended pattern in enterprise COBOL is: - Always define FILE STATUS on every file - Use DECLARATIVES for centralized error logging - Use inline exception phrases for expected conditions (AT END for normal EOF, INVALID KEY for expected not-found) - Always check file status after OPEN and CLOSE (which do not have inline exception phrases in standard COBOL) When an inline phrase handles the condition, the declarative is skipped, but the file status field still contains the error code and can be examined by the inline handler.

Question 24

What is the ON EXCEPTION phrase on the CALL statement used for?

Show Answer The **ON EXCEPTION** phrase on the CALL statement handles the condition where the called program **cannot be found** or loaded. This is not a file I/O error but a program-loading error:
           CALL 'VALMOD01' USING WS-INPUT-DATA
                                 WS-OUTPUT-DATA
               ON EXCEPTION
                   DISPLAY 'PROGRAM VALMOD01 NOT FOUND'
                   MOVE 16 TO WS-RETURN-CODE
               NOT ON EXCEPTION
                   MOVE WS-OUTPUT-RC TO WS-RETURN-CODE
           END-CALL
Without ON EXCEPTION, a failed CALL abends the program. With it, the program can handle the missing subprogram gracefully -- for example, by logging the error and using a default behavior. Common causes of CALL exceptions: misspelled program name, missing load module in STEPLIB, insufficient region size to load the subprogram.

Question 25

What are the two characters that make up a file status code, and what does each represent?

Show Answer A file status code consists of two characters called **status key 1** and **status key 2**: **Status key 1** (first character) indicates the general category: - **0** = Successful (or successful with informational condition) - **1** = AT END condition - **2** = Invalid key condition - **3** = Permanent error - **4** = Logic error - **9** = Implementor-defined (vendor-specific) **Status key 2** (second character) provides the specific condition within the category. For example, in status code **23**: - Status key 1 = **2** (invalid key category) - Status key 2 = **3** (record not found) IBM COBOL also supports an extended file status through VSAM return codes (VSAM-STATUS), which provides more granular information in a separate field. The standard two-character code is sufficient for most error handling, but VSAM-specific debugging may require the extended codes.