Why Explicit Error Handling Matters in COBOL
Unlike languages with built-in try/catch exception frameworks, classic COBOL requires the programmer to explicitly check for error conditions after nearly every I/O or arithmetic statement, because without that checking the runtime either silently continues with corrupted results or abends the entire job step. A batch program that reads a file without checking FILE STATUS after each READ, for instance, will not automatically detect end-of-file or a record-not-found condition unless the programmer has coded an AT END or INVALID KEY clause, or wired up a FILE STATUS check, to catch it. This explicit, statement-by-statement discipline is a defining characteristic of COBOL error handling, and mainframe shops that skip it routinely suffer abends deep into multi-hour batch runs that then require an operator to diagnose from a dump.
Cricket analogy: Skipping error checks in COBOL is like a fielder not checking whether they've actually gathered the ball cleanly before throwing to the stumps; without that explicit check, a misfield can go unnoticed until the run-out attempt fails at the worst moment.
FILE STATUS Codes and I/O Error Checking
Declaring a two-character FILE STATUS field in the SELECT clause, such as SELECT CUSTFILE ASSIGN TO CUSTDD FILE STATUS IS WS-CUST-STATUS, causes the runtime to populate that field after every OPEN, READ, WRITE, REWRITE, DELETE, and CLOSE against the file, letting the program branch on the two-digit code immediately afterward. A status of '00' means the operation succeeded, '10' signals end-of-file on a sequential READ, '23' means record-not-found on an indexed READ by key, and '35' means the OPEN failed because the file does not exist, and disciplined programs check WS-CUST-STATUS after every single I/O verb rather than assuming success. Many shops standardize this pattern by writing a single shared paragraph, such as 9000-CHECK-FILE-STATUS, invoked via PERFORM after each I/O operation, so that unexpected status codes are logged and the program terminates cleanly with a meaningful message instead of an unexplained abend.
Cricket analogy: A FILE STATUS code is like the third umpire's decision review readout, DECISION: OUT or DECISION: NOT OUT, giving the on-field umpire an explicit two-part signal to act on rather than guessing what happened on a close run-out.
ON SIZE ERROR, ON OVERFLOW, and Declaratives
Arithmetic statements such as COMPUTE, ADD, SUBTRACT, MULTIPLY, and DIVIDE support an optional ON SIZE ERROR imperative-statement clause that executes only when the result would overflow the receiving field's PICTURE clause or when a division by zero is attempted, letting the program substitute a default, log a warning, or branch to cleanup logic instead of silently truncating a financial total. STRING and UNSTRING statements have an analogous ON OVERFLOW clause that fires when the receiving field is too small to hold the concatenated or split result. For broader, file-level exception handling across many paragraphs, COBOL's DECLARATIVES section, placed at the start of the PROCEDURE DIVISION and paired with USE AFTER STANDARD ERROR PROCEDURE ON file-name, lets a program centralize I/O error handling for a specific file so every READ or WRITE against it automatically triggers the declarative paragraph on any non-successful FILE STATUS, without a manual check after every single statement.
Cricket analogy: ON SIZE ERROR is like a stadium's electronic scoreboard having a built-in rule for when a team's total would exceed the display's digit limit, triggering a special overflow indicator rather than showing a wrapped, meaningless number.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-CUST-STATUS PIC XX.
01 WS-TOTAL-AMOUNT PIC 9(5)V99.
01 WS-INCREMENT PIC 9(5)V99 VALUE 99999.99.
PROCEDURE DIVISION.
READ CUSTFILE
INVALID KEY
DISPLAY 'CUSTOMER NOT FOUND: ' WS-CUST-STATUS
END-READ
IF WS-CUST-STATUS NOT = '00' AND WS-CUST-STATUS NOT = '23'
PERFORM 9000-FILE-ERROR-ABORT
END-IF
ADD WS-INCREMENT TO WS-TOTAL-AMOUNT
ON SIZE ERROR
DISPLAY 'TOTAL WOULD OVERFLOW, CAPPING VALUE'
MOVE 99999.99 TO WS-TOTAL-AMOUNT
END-ADD.The most common FILE STATUS codes to memorize: '00' success, '10' end-of-file, '22' duplicate key on WRITE/REWRITE, '23' record not found, '35' file not found on OPEN, and '9x' codes indicate implementation-specific or environment errors that usually require checking the vendor's runtime documentation.
Relying only on the compiler's default action for an unhandled AT END or INVALID KEY condition is dangerous: if no explicit clause is coded, some COBOL environments simply continue to the next statement with the record area unchanged, silently reprocessing the last successfully read record and corrupting downstream totals, rather than stopping the program.
- COBOL requires explicit, statement-by-statement error checking rather than providing automatic exception propagation like try/catch.
- FILE STATUS is a two-character field populated after every I/O verb, with '00' meaning success and other codes indicating specific conditions.
- AT END and INVALID KEY clauses handle end-of-file and key-not-found conditions directly on READ statements.
- ON SIZE ERROR catches arithmetic overflow or division by zero on COMPUTE, ADD, SUBTRACT, MULTIPLY, and DIVIDE.
- ON OVERFLOW catches insufficient receiving-field space on STRING and UNSTRING statements.
- DECLARATIVES with USE AFTER STANDARD ERROR PROCEDURE centralizes I/O error handling across all operations on a given file.
- Failing to code explicit error clauses can let a program silently continue with corrupted or stale data instead of failing safely.
Practice what you learned
1. What FILE STATUS value indicates a successful I/O operation?
2. Which clause on an arithmetic statement like COMPUTE catches a result that would overflow the receiving field?
3. What does a FILE STATUS of '23' typically indicate on an indexed READ?
4. What does the DECLARATIVES section combined with USE AFTER STANDARD ERROR PROCEDURE achieve?
5. What is the risk of not coding an explicit AT END or INVALID KEY clause on a READ statement?
Was this page helpful?
You May Also Like
Subprograms and CALL Statements
Learn how COBOL programs invoke reusable subprograms with the CALL statement, pass parameters via the LINKAGE SECTION, and choose between static and dynamic linkage.
COBOL and DB2
Learn how COBOL programs embed SQL to interact with a DB2 relational database, using host variables, cursors, and SQLCA/SQLCODE for error checking.
CICS Fundamentals for COBOL
Learn how CICS (Customer Information Control System) lets COBOL programs run as online, transaction-based applications, using pseudo-conversational design, EXEC CICS commands, and the COMMAREA.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics