File status variables are a critical component of robust COBOL file handling. They provide a standardized way to detect and respond to the results of file operations, allowing programs to handle both successful operations and various error conditions.
1234567891011121314151617181920ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT CUSTOMER-FILE ASSIGN TO "CUSTOMER.DAT" ORGANIZATION IS SEQUENTIAL ACCESS MODE IS SEQUENTIAL FILE STATUS IS CUSTOMER-STATUS. DATA DIVISION. FILE SECTION. FD CUSTOMER-FILE LABEL RECORDS ARE STANDARD. 01 CUSTOMER-RECORD PIC X(100). WORKING-STORAGE SECTION. 01 CUSTOMER-STATUS PIC XX. 88 STATUS-SUCCESS VALUE "00". 88 END-OF-FILE VALUE "10". 88 FILE-NOT-FOUND VALUE "35".
1234567891011121314151617181920212223242526272829303132* Method 1: Direct status code comparison OPEN INPUT CUSTOMER-FILE IF CUSTOMER-STATUS = "00" PERFORM PROCESS-FILE ELSE DISPLAY "Error opening file: " CUSTOMER-STATUS END-IF * Method 2: Using 88-level conditions OPEN INPUT CUSTOMER-FILE IF STATUS-SUCCESS PERFORM PROCESS-FILE ELSE IF FILE-NOT-FOUND DISPLAY "Customer file not found" PERFORM CREATE-EMPTY-FILE ELSE DISPLAY "Unexpected error: " CUSTOMER-STATUS END-IF * Method 3: Comprehensive condition handling OPEN INPUT CUSTOMER-FILE EVALUATE CUSTOMER-STATUS WHEN "00" PERFORM PROCESS-FILE WHEN "35" DISPLAY "File not found" PERFORM CREATE-EMPTY-FILE WHEN "37" DISPLAY "Access denied - check permissions" WHEN OTHER DISPLAY "Unexpected error: " CUSTOMER-STATUS END-EVALUATE
These examples demonstrate different approaches to checking file status. The 88-level conditions and EVALUATE statement make the code more readable and maintainable compared to direct status code comparisons.
Some COBOL implementations support an extended file status, which provides more detailed information about file operations.
1234567891011121314151617181920212223ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT CUSTOMER-FILE ASSIGN TO "CUSTOMER.DAT" ORGANIZATION IS SEQUENTIAL FILE STATUS IS EXTENDED-STATUS. DATA DIVISION. WORKING-STORAGE SECTION. 01 EXTENDED-STATUS. 05 PRIMARY-STATUS PIC XX. 88 STATUS-SUCCESS VALUE "00". 88 END-OF-FILE VALUE "10". 05 SECONDARY-STATUS PIC XXX. PROCEDURE DIVISION. MAIN-LOGIC. OPEN INPUT CUSTOMER-FILE IF NOT STATUS-SUCCESS DISPLAY "Error: " PRIMARY-STATUS "-" SECONDARY-STATUS * Secondary status provides more details about the error END-IF
The extended file status typically consists of the standard two-character status code plus additional implementation-specific details in the secondary status. This provides more granular information about errors, helping with troubleshooting.
COBOL file status codes follow a structured pattern. The first digit generally indicates the category of the status, while the second digit provides more specific information. Understanding these codes is essential for effective error handling.
First Digit | Category | Description |
---|---|---|
0 | Successful | Operation completed normally |
1 | At End | End of file or key range reached |
2 | Invalid Key | Key-related issue (indexed/relative files) |
3 | Permanent Error | Physical or hardware error |
4 | Logic Error | Program or operation sequence error |
9 | Implementor-Defined | Implementation-specific conditions |
Status | Description | Operations | Handling Approach |
---|---|---|---|
"00" | Successful completion | All operations | Continue normal processing |
"10" | End of file reached | READ | Normal condition; finalize processing |
"35" | File not found | OPEN INPUT, I-O | Create file or check path/name |
"37" | File access denied | OPEN | Check permissions or file sharing |
"39" | File attribute conflict | OPEN | Check record definition or ASSIGN |
"41" | File already open | OPEN | Close file before reopening |
"42" | File not open | CLOSE, READ, WRITE | Open file before operation |
"43" | Required file access not taken | DELETE, REWRITE | READ record before operation |
"46" | Read beyond file end | READ | Reset file position or check logic |
"47" | File not open in required mode | I/O operations | Open file in correct mode |
"48" | File locked | I/O operations | Wait and retry or check lock status |
"90-99" | Implementation-defined error | Various | Check documentation for system |
Status | Description | Operations | Handling Approach |
---|---|---|---|
"21" | Key sequence error | WRITE | Ensure records are in key sequence |
"22" | Duplicate key | WRITE, REWRITE | Use unique key or update existing |
"23" | Record not found | READ, REWRITE, DELETE | Verify key or handle missing record |
"24" | Boundary violation | WRITE, START | Check key range or record size |
123456789101112131415161718192021222324252627282930313233343536WORKING-STORAGE SECTION. 01 FILE-STATUS-CODES. 05 CUSTOMER-STATUS PIC XX. * Success indicators 88 STATUS-OK VALUE "00". 88 END-OF-FILE VALUE "10". * Key-related errors 88 DUPLICATE-KEY VALUE "22". 88 RECORD-NOT-FOUND VALUE "23". * Open/access errors 88 FILE-NOT-FOUND VALUE "35". 88 ACCESS-DENIED VALUE "37". 88 FILE-ALREADY-OPEN VALUE "41". 88 FILE-NOT-OPEN VALUE "42". * General error classification 88 OPERATION-SUCCESS VALUE "00". 88 AT-END-CONDITION VALUE "10". 88 KEY-ERROR VALUE "21" "22" "23" "24". 88 PERMANENT-ERROR VALUE "30" THRU "39". 88 LOGIC-ERROR VALUE "40" THRU "49". 88 SERIOUS-ERROR VALUE "90" THRU "99". * Usage example READ CUSTOMER-FILE IF STATUS-OK PROCESS-RECORD ELSE IF END-OF-FILE PERFORM END-OF-PROCESSING ELSE IF RECORD-NOT-FOUND DISPLAY "Customer record not found" ELSE IF KEY-ERROR DISPLAY "Key error: " CUSTOMER-STATUS END-IF
Using 88-level condition names makes code more readable and self-documenting. It allows logical grouping of status codes by both specific conditions and general categories.
Effective error recovery goes beyond simply detecting errors through file status. Robust COBOL programs implement strategies to handle, recover from, and continue processing despite file-related issues.
123456789101112131415161718192021222324252627282930313233343536373839404142PROCEDURE DIVISION. MAIN-PROCESS. PERFORM INITIALIZATION IF NOT ERROR-OCCURRED PERFORM PROCESS-RECORDS UNTIL END-OF-FILE OR ERROR-OCCURRED END-IF PERFORM TERMINATION STOP RUN. INITIALIZATION. OPEN INPUT CUSTOMER-FILE PERFORM CHECK-FILE-STATUS OPEN OUTPUT REPORT-FILE PERFORM CHECK-FILE-STATUS. PROCESS-RECORDS. READ CUSTOMER-FILE AT END SET END-OF-FILE TO TRUE END-READ PERFORM CHECK-FILE-STATUS IF NOT END-OF-FILE AND NOT ERROR-OCCURRED PERFORM PROCESS-CUSTOMER END-IF. CHECK-FILE-STATUS. EVALUATE TRUE WHEN STATUS-OK CONTINUE WHEN END-OF-FILE IF NOT CUSTOMER-OPERATION * End of file only valid for reads DISPLAY "Unexpected end of file" SET ERROR-OCCURRED TO TRUE END-IF WHEN FILE-NOT-FOUND DISPLAY "File not found: " CURRENT-FILE SET ERROR-OCCURRED TO TRUE WHEN OTHER DISPLAY "File error " FILE-STATUS " on " CURRENT-FILE DISPLAY "Operation: " CURRENT-OPERATION SET ERROR-OCCURRED TO TRUE END-EVALUATE.
A centralized error handling routine simplifies code maintenance and ensures consistent error handling throughout the program. The CHECK-FILE-STATUS paragraph is called after each file operation.
1234567891011121314151617181920212223242526272829303132WORKING-STORAGE SECTION. 01 RETRY-VARIABLES. 05 RETRY-COUNTER PIC 9(3) VALUE ZERO. 05 MAX-RETRIES PIC 9(3) VALUE 3. 05 RETRY-DELAY PIC 9(3) VALUE 2. PROCEDURE DIVISION. FILE-OPERATION-WITH-RETRY. MOVE ZERO TO RETRY-COUNTER PERFORM UNTIL RETRY-COUNTER > MAX-RETRIES OR STATUS-OK ADD 1 TO RETRY-COUNTER * Attempt the file operation OPEN I-O CUSTOMER-FILE EVALUATE TRUE WHEN STATUS-OK CONTINUE WHEN FILE-LOCKED IF RETRY-COUNTER < MAX-RETRIES DISPLAY "File locked, retry " RETRY-COUNTER " of " MAX-RETRIES CALL "C$SLEEP" USING RETRY-DELAY ELSE DISPLAY "Maximum retries exceeded" END-IF WHEN OTHER * Non-retryable error DISPLAY "Fatal error: " FILE-STATUS MOVE MAX-RETRIES TO RETRY-COUNTER END-EVALUATE END-PERFORM.
This pattern implements an automatic retry mechanism for transient errors such as file locks in a multi-user environment. It includes a delay between attempts and limits the number of retries.
123456789101112131415161718192021222324252627282930313233343536373839404142* Example: Handling a missing master file by using backup PERFORM OPEN-MASTER-FILE IF FILE-NOT-FOUND DISPLAY "Primary file not found, trying backup file" PERFORM OPEN-BACKUP-FILE IF STATUS-OK SET USING-BACKUP TO TRUE PERFORM LOG-BACKUP-USAGE ELSE DISPLAY "Cannot open primary or backup file" SET FATAL-ERROR TO TRUE END-IF END-IF * Example: Creating a file if it doesn't exist OPEN I-O TRANSACTION-LOG IF FILE-NOT-FOUND DISPLAY "Transaction log not found, creating new file" CLOSE TRANSACTION-LOG OPEN OUTPUT TRANSACTION-LOG IF STATUS-OK PERFORM WRITE-LOG-HEADER CLOSE TRANSACTION-LOG OPEN I-O TRANSACTION-LOG END-IF END-IF * Example: Skipping bad records and continuing PERFORM UNTIL END-OF-FILE READ INPUT-FILE AT END SET END-OF-FILE TO TRUE END-READ IF NOT END-OF-FILE IF VALID-RECORD PERFORM PROCESS-RECORD ELSE ADD 1 TO ERROR-RECORD-COUNT PERFORM WRITE-TO-ERROR-FILE END-IF END-IF END-PERFORM
These examples demonstrate different recovery strategies: falling back to backup files, automatically creating missing files, and skipping bad records to continue processing.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576IDENTIFICATION DIVISION. PROGRAM-ID. ERRORLOG. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT ERROR-LOG ASSIGN TO "ERRORLOG.DAT" ORGANIZATION IS SEQUENTIAL ACCESS MODE IS SEQUENTIAL. DATA DIVISION. FILE SECTION. FD ERROR-LOG RECORD CONTAINS 200 CHARACTERS. 01 ERROR-RECORD PIC X(200). WORKING-STORAGE SECTION. 01 ERROR-LOG-FIELDS. 05 LOG-TIMESTAMP PIC X(26). 05 LOG-PROGRAM-ID PIC X(8). 05 LOG-FILE-NAME PIC X(30). 05 LOG-OPERATION PIC X(10). 05 LOG-STATUS-CODE PIC XX. 05 LOG-RECORD-KEY PIC X(20). 05 LOG-MESSAGE PIC X(100). 01 ERROR-LOG-RECORD. 05 LOG-DATETIME PIC X(26). 05 FILLER PIC X VALUE '|'. 05 LOG-PROGRAM PIC X(8). 05 FILLER PIC X VALUE '|'. 05 LOG-FILE PIC X(30). 05 FILLER PIC X VALUE '|'. 05 LOG-OPER PIC X(10). 05 FILLER PIC X VALUE '|'. 05 LOG-STATUS PIC XX. 05 FILLER PIC X VALUE '|'. 05 LOG-KEY PIC X(20). 05 FILLER PIC X VALUE '|'. 05 LOG-MSG PIC X(100). PROCEDURE DIVISION. LOG-FILE-ERROR. * Get current date and time MOVE FUNCTION CURRENT-DATE TO LOG-TIMESTAMP * Set log fields from parameters MOVE "CUSTMAIN" TO LOG-PROGRAM-ID MOVE "CUSTOMER.DAT" TO LOG-FILE-NAME MOVE "READ" TO LOG-OPERATION MOVE "23" TO LOG-STATUS-CODE MOVE "12345" TO LOG-RECORD-KEY MOVE "Customer record not found" TO LOG-MESSAGE * Format the log record PERFORM FORMAT-LOG-RECORD * Write to log file PERFORM WRITE-LOG-RECORD . FORMAT-LOG-RECORD. MOVE LOG-TIMESTAMP TO LOG-DATETIME MOVE LOG-PROGRAM-ID TO LOG-PROGRAM MOVE LOG-FILE-NAME TO LOG-FILE MOVE LOG-OPERATION TO LOG-OPER MOVE LOG-STATUS-CODE TO LOG-STATUS MOVE LOG-RECORD-KEY TO LOG-KEY MOVE LOG-MESSAGE TO LOG-MSG . WRITE-LOG-RECORD. OPEN EXTEND ERROR-LOG WRITE ERROR-RECORD FROM ERROR-LOG-RECORD CLOSE ERROR-LOG .
A robust error logging system captures detailed information about each error, including timestamp, program ID, file name, operation, status code, record key, and a descriptive message. This information is invaluable for troubleshooting.
Error Condition | Status Code | Recovery Strategy |
---|---|---|
File not found | "35" | Create file, use backup, or alert user |
Duplicate key | "22" | Generate unique key or update existing record |
Record not found | "23" | Create default record or skip processing |
File locked | "48" | Implement retry mechanism with timeout |
Disk full | "34" | Free space, use alternate location, or compress |
Hardware error | "30" | Notify operations, use disaster recovery plan |
COBOL provides two key structured error handling mechanisms for file operations: the AT END clause for sequential access and the INVALID KEY clause for indexed and relative files. These clauses complement file status checking and provide inline error handling.
The AT END clause handles the condition when a READ operation attempts to read beyond the end of a file. This is commonly used with sequential file processing.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768* Basic AT END structure READ CUSTOMER-FILE INTO WS-CUSTOMER-RECORD AT END SET END-OF-FILE TO TRUE NOT AT END ADD 1 TO RECORD-COUNT PERFORM PROCESS-CUSTOMER END-READ * Complete example with AT END IDENTIFICATION DIVISION. PROGRAM-ID. ATENDEXMP. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT CUSTOMER-FILE ASSIGN TO "CUSTOMER.DAT" ORGANIZATION IS SEQUENTIAL ACCESS MODE IS SEQUENTIAL FILE STATUS IS CUSTOMER-STATUS. DATA DIVISION. FILE SECTION. FD CUSTOMER-FILE LABEL RECORDS ARE STANDARD. 01 CUSTOMER-RECORD PIC X(100). WORKING-STORAGE SECTION. 01 WS-CUSTOMER-RECORD PIC X(100). 01 CUSTOMER-STATUS PIC XX. 01 EOF-FLAG PIC X VALUE "N". 88 END-OF-FILE VALUE "Y". 01 RECORD-COUNT PIC 9(5) VALUE ZERO. PROCEDURE DIVISION. MAIN-PROCESS. PERFORM INITIALIZATION PERFORM PROCESS-RECORDS UNTIL END-OF-FILE PERFORM TERMINATION STOP RUN. INITIALIZATION. OPEN INPUT CUSTOMER-FILE IF CUSTOMER-STATUS NOT = "00" DISPLAY "Error opening file: " CUSTOMER-STATUS MOVE "Y" TO EOF-FLAG END-IF. PROCESS-RECORDS. READ CUSTOMER-FILE INTO WS-CUSTOMER-RECORD AT END SET END-OF-FILE TO TRUE DISPLAY "End of file reached" NOT AT END ADD 1 TO RECORD-COUNT DISPLAY "Processing record " RECORD-COUNT END-READ * Check status for other errors IF NOT END-OF-FILE AND CUSTOMER-STATUS NOT = "00" DISPLAY "Error reading file: " CUSTOMER-STATUS MOVE "Y" TO EOF-FLAG END-IF. TERMINATION. CLOSE CUSTOMER-FILE DISPLAY "Total records processed: " RECORD-COUNT.
The INVALID KEY clause handles key-related errors in indexed and relative files, such as record not found, duplicate key, or boundary violations.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115* Basic INVALID KEY structure READ CUSTOMER-FILE KEY IS CUSTOMER-ID INVALID KEY DISPLAY "Customer " CUSTOMER-ID " not found" NOT INVALID KEY PERFORM PROCESS-CUSTOMER END-READ * INVALID KEY with WRITE WRITE CUSTOMER-RECORD INVALID KEY EVALUATE CUSTOMER-STATUS WHEN "22" DISPLAY "Duplicate customer ID: " CUSTOMER-ID WHEN "24" DISPLAY "Key out of allowed range" WHEN OTHER DISPLAY "Error: " CUSTOMER-STATUS END-EVALUATE NOT INVALID KEY ADD 1 TO RECORDS-ADDED END-WRITE * Complete example with INVALID KEY IDENTIFICATION DIVISION. PROGRAM-ID. INVKEYEXMP. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT CUSTOMER-FILE ASSIGN TO "CUSTOMER.IDX" ORGANIZATION IS INDEXED ACCESS MODE IS RANDOM RECORD KEY IS CUST-ID FILE STATUS IS CUSTOMER-STATUS. DATA DIVISION. FILE SECTION. FD CUSTOMER-FILE LABEL RECORDS ARE STANDARD. 01 CUSTOMER-RECORD. 05 CUST-ID PIC 9(5). 05 CUST-NAME PIC X(30). 05 CUST-ADDRESS PIC X(50). 05 CUST-BALANCE PIC S9(7)V99. WORKING-STORAGE SECTION. 01 CUSTOMER-STATUS PIC XX. 01 SEARCH-ID PIC 9(5). 01 VALID-DATA PIC X VALUE "Y". 01 PROCESSING-FLAG PIC X VALUE "Y". 88 CONTINUE-PROCESSING VALUE "Y". PROCEDURE DIVISION. MAIN-PROCESS. PERFORM INITIALIZATION PERFORM UNTIL NOT CONTINUE-PROCESSING DISPLAY "Enter customer ID (0 to quit): " ACCEPT SEARCH-ID IF SEARCH-ID = 0 MOVE "N" TO PROCESSING-FLAG ELSE PERFORM LOOKUP-CUSTOMER END-IF END-PERFORM PERFORM TERMINATION STOP RUN. INITIALIZATION. OPEN I-O CUSTOMER-FILE IF CUSTOMER-STATUS NOT = "00" DISPLAY "Error opening file: " CUSTOMER-STATUS MOVE "N" TO PROCESSING-FLAG END-IF. LOOKUP-CUSTOMER. MOVE SEARCH-ID TO CUST-ID READ CUSTOMER-FILE INVALID KEY EVALUATE CUSTOMER-STATUS WHEN "23" DISPLAY "Customer " SEARCH-ID " not found" DISPLAY "Would you like to add this customer? (Y/N)" ACCEPT VALID-DATA IF VALID-DATA = "Y" PERFORM ADD-NEW-CUSTOMER END-IF WHEN OTHER DISPLAY "Error: " CUSTOMER-STATUS END-EVALUATE NOT INVALID KEY DISPLAY "Customer found: " CUST-NAME DISPLAY "Balance: " CUST-BALANCE END-READ. ADD-NEW-CUSTOMER. MOVE SEARCH-ID TO CUST-ID DISPLAY "Enter customer name: " ACCEPT CUST-NAME DISPLAY "Enter customer address: " ACCEPT CUST-ADDRESS MOVE ZERO TO CUST-BALANCE WRITE CUSTOMER-RECORD INVALID KEY DISPLAY "Error adding customer: " CUSTOMER-STATUS NOT INVALID KEY DISPLAY "Customer added successfully" END-WRITE. TERMINATION. CLOSE CUSTOMER-FILE.
For comprehensive error handling, combine AT END/INVALID KEY clauses with file status checking. This ensures that both expected conditions and unexpected errors are properly handled.
12345678910111213141516171819202122232425262728293031323334* Example with both mechanisms READ CUSTOMER-FILE NEXT RECORD AT END SET END-OF-FILE TO TRUE NOT AT END ADD 1 TO RECORD-COUNT END-READ * Check for other errors IF NOT END-OF-FILE IF CUSTOMER-STATUS NOT = "00" DISPLAY "Error reading file: " CUSTOMER-STATUS PERFORM ERROR-HANDLING-ROUTINE ELSE PERFORM PROCESS-RECORD END-IF END-IF * Example for indexed file READ CUSTOMER-FILE KEY IS CUSTOMER-ID INVALID KEY IF CUSTOMER-STATUS = "23" DISPLAY "Customer " CUSTOMER-ID " not found" ELSE DISPLAY "Unexpected key error: " CUSTOMER-STATUS END-IF END-READ * Additional status check for unexpected errors IF CUSTOMER-STATUS NOT = "00" AND CUSTOMER-STATUS NOT = "23" DISPLAY "Serious error occurred: " CUSTOMER-STATUS PERFORM ERROR-RECOVERY-ROUTINE END-IF
This pattern provides the most comprehensive error handling. The clauses handle expected conditions (end of file, record not found), while the file status checks catch any other unexpected errors.
Approach | Advantages | Limitations | Best For |
---|---|---|---|
File Status Only | Catches all error types, Centralized handling | More verbose code, Separated from file operation | Complex error recovery logic |
AT END / INVALID KEY | Inline with operation, More readable | Limited to specific error types | Expected conditions in routine processing |
Combined Approach | Comprehensive, Handles all scenarios | More complex code structure | Production systems requiring robust handling |
88-Level Conditions | Readable code, Self-documenting | Requires additional definitions | Any approach for improved readability |
Proper file exception handling in COBOL combines all the techniques we've discussed into a comprehensive approach. This ensures that programs can detect, report, and recover from a wide range of file-related issues while maintaining data integrity.
Pitfall | Consequence | Better Approach |
---|---|---|
Ignoring file status | Undetected errors, data corruption | Check status after every operation |
Relying only on AT END / INVALID KEY | Missing non-standard errors | Combine with status checking |
Generic error handling | Limited recovery options | Error-specific recovery strategies |
Not closing files after errors | Resource leaks, locked files | Close files in termination routine |
Poor error messages | Difficult troubleshooting | Include operation, file, and status |
Not validating input data | Preventable errors | Validate before file operations |
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240IDENTIFICATION DIVISION. PROGRAM-ID. FILEHDLR. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT CUSTOMER-FILE ASSIGN TO "CUSTOMER.IDX" ORGANIZATION IS INDEXED ACCESS MODE IS DYNAMIC RECORD KEY IS CUST-ID ALTERNATE RECORD KEY IS CUST-NAME WITH DUPLICATES FILE STATUS IS CUSTOMER-STATUS. SELECT ERROR-LOG ASSIGN TO "ERRORLOG.DAT" ORGANIZATION IS SEQUENTIAL ACCESS MODE IS SEQUENTIAL FILE STATUS IS LOG-STATUS. DATA DIVISION. FILE SECTION. FD CUSTOMER-FILE LABEL RECORDS ARE STANDARD. 01 CUSTOMER-RECORD. 05 CUST-ID PIC 9(5). 05 CUST-NAME PIC X(30). 05 CUST-ADDRESS PIC X(50). 05 CUST-BALANCE PIC S9(7)V99. FD ERROR-LOG LABEL RECORDS ARE STANDARD. 01 LOG-RECORD PIC X(200). WORKING-STORAGE SECTION. 01 FILE-STATUS-FIELDS. 05 CUSTOMER-STATUS PIC XX. 88 CUST-SUCCESS VALUE "00". 88 CUST-EOF VALUE "10". 88 CUST-DUPLICATE VALUE "22". 88 CUST-NOT-FOUND VALUE "23". 88 CUST-NOT-EXISTS VALUE "35". 05 LOG-STATUS PIC XX. 05 CURRENT-FILE PIC X(30) VALUE SPACES. 05 CURRENT-OPERATION PIC X(10) VALUE SPACES. 01 PROGRAM-FLAGS. 05 ERROR-FLAG PIC X VALUE "N". 88 ERROR-OCCURRED VALUE "Y". 05 EOF-FLAG PIC X VALUE "N". 88 END-OF-FILE VALUE "Y". 05 RETRY-COUNTER PIC 9(3) VALUE ZERO. 05 MAX-RETRIES PIC 9(3) VALUE 3. 01 SEARCH-ID PIC 9(5). 01 LOG-FIELDS. 05 LOG-TIMESTAMP PIC X(26). 05 LOG-FORMATTED PIC X(200). PROCEDURE DIVISION. MAIN-PROCESS. PERFORM INITIALIZATION IF NOT ERROR-OCCURRED PERFORM PROCESS-RECORDS UNTIL END-OF-FILE OR ERROR-OCCURRED END-IF PERFORM TERMINATION STOP RUN. INITIALIZATION. MOVE "CUSTOMER.IDX" TO CURRENT-FILE MOVE "OPEN" TO CURRENT-OPERATION OPEN I-O CUSTOMER-FILE PERFORM CHECK-FILE-STATUS IF CUST-NOT-EXISTS DISPLAY "Customer file not found. Creating new file." CLOSE CUSTOMER-FILE OPEN OUTPUT CUSTOMER-FILE PERFORM CHECK-FILE-STATUS IF NOT ERROR-OCCURRED CLOSE CUSTOMER-FILE OPEN I-O CUSTOMER-FILE PERFORM CHECK-FILE-STATUS END-IF END-IF. PROCESS-RECORDS. DISPLAY "Enter customer ID (0 to quit): " ACCEPT SEARCH-ID IF SEARCH-ID = ZERO SET END-OF-FILE TO TRUE ELSE PERFORM READ-CUSTOMER IF NOT ERROR-OCCURRED IF CUST-NOT-FOUND DISPLAY "Customer not found. Add new customer? (Y/N)" ACCEPT EOF-FLAG IF EOF-FLAG = "Y" PERFORM ADD-CUSTOMER END-IF ELSE DISPLAY "Customer found: " CUST-NAME DISPLAY "Balance: " CUST-BALANCE DISPLAY "Update this customer? (Y/N)" ACCEPT EOF-FLAG IF EOF-FLAG = "Y" PERFORM UPDATE-CUSTOMER END-IF END-IF END-IF END-IF. READ-CUSTOMER. MOVE "READ" TO CURRENT-OPERATION MOVE SEARCH-ID TO CUST-ID READ CUSTOMER-FILE INVALID KEY IF CUST-NOT-FOUND CONTINUE ELSE PERFORM LOG-ERROR END-IF END-READ PERFORM CHECK-FILE-STATUS. ADD-CUSTOMER. MOVE "WRITE" TO CURRENT-OPERATION MOVE SEARCH-ID TO CUST-ID DISPLAY "Enter customer name: " ACCEPT CUST-NAME DISPLAY "Enter customer address: " ACCEPT CUST-ADDRESS MOVE ZERO TO CUST-BALANCE WRITE CUSTOMER-RECORD INVALID KEY PERFORM LOG-ERROR NOT INVALID KEY DISPLAY "Customer added successfully" END-WRITE PERFORM CHECK-FILE-STATUS. UPDATE-CUSTOMER. MOVE "REWRITE" TO CURRENT-OPERATION DISPLAY "Enter new customer name (or ENTER to keep): " ACCEPT EOF-FLAG IF EOF-FLAG NOT = SPACES MOVE EOF-FLAG TO CUST-NAME END-IF DISPLAY "Enter new address (or ENTER to keep): " ACCEPT EOF-FLAG IF EOF-FLAG NOT = SPACES MOVE EOF-FLAG TO CUST-ADDRESS END-IF DISPLAY "Enter new balance (or ENTER to keep): " ACCEPT EOF-FLAG IF EOF-FLAG NOT = SPACES MOVE FUNCTION NUMVAL(EOF-FLAG) TO CUST-BALANCE END-IF REWRITE CUSTOMER-RECORD INVALID KEY PERFORM LOG-ERROR NOT INVALID KEY DISPLAY "Customer updated successfully" END-REWRITE PERFORM CHECK-FILE-STATUS. CHECK-FILE-STATUS. EVALUATE TRUE WHEN CUST-SUCCESS CONTINUE WHEN CUST-EOF SET END-OF-FILE TO TRUE WHEN CUST-NOT-FOUND * Not an error for our program logic CONTINUE WHEN OTHER PERFORM LOG-ERROR END-EVALUATE. LOG-ERROR. SET ERROR-OCCURRED TO TRUE DISPLAY "Error on " CURRENT-OPERATION " for " CURRENT-FILE DISPLAY "Status code: " CUSTOMER-STATUS * Log error to file MOVE FUNCTION CURRENT-DATE TO LOG-TIMESTAMP STRING LOG-TIMESTAMP DELIMITED BY SIZE " | FILEHDLR | " CURRENT-FILE DELIMITED BY SPACE " | " DELIMITED BY SIZE CURRENT-OPERATION DELIMITED BY SPACE " | " DELIMITED BY SIZE CUSTOMER-STATUS DELIMITED BY SIZE " | " DELIMITED BY SIZE "Cust ID: " DELIMITED BY SIZE CUST-ID DELIMITED BY SIZE INTO LOG-FORMATTED END-STRING MOVE "ERRORLOG.DAT" TO CURRENT-FILE MOVE "WRITE" TO CURRENT-OPERATION OPEN EXTEND ERROR-LOG IF LOG-STATUS = "00" MOVE LOG-FORMATTED TO LOG-RECORD WRITE LOG-RECORD CLOSE ERROR-LOG ELSE DISPLAY "Could not open error log" END-IF. TERMINATION. MOVE "CLOSE" TO CURRENT-OPERATION CLOSE CUSTOMER-FILE IF CUSTOMER-STATUS NOT = "00" DISPLAY "Warning: Error closing " CURRENT-FILE DISPLAY "Status: " CUSTOMER-STATUS END-IF IF ERROR-OCCURRED DISPLAY "Program completed with errors" ELSE DISPLAY "Program completed successfully" END-IF.
This comprehensive example demonstrates best practices for file exception handling:
In multi-user environments, additional considerations for file handling include:
123456789101112131415161718192021* Example of retry logic for locked records PERFORM WITH TEST AFTER UNTIL STATUS-OK OR RETRY-COUNTER > MAX-RETRIES ADD 1 TO RETRY-COUNTER READ CUSTOMER-FILE WITH LOCK INVALID KEY PERFORM CHECK-INVALID-KEY END-READ IF CUSTOMER-STATUS = "48" OR CUSTOMER-STATUS = "9D" * Record or file is locked DISPLAY "Record locked, retry attempt " RETRY-COUNTER * Wait a moment before retrying CALL "C$SLEEP" USING 2 END-IF END-PERFORM IF RETRY-COUNTER > MAX-RETRIES DISPLAY "Maximum retries exceeded - record still locked" SET ERROR-OCCURRED TO TRUE END-IF
This example shows a retry mechanism for handling locked records in a multi-user environment. The program attempts to read the record multiple times with a delay between attempts.
Robust file exception handling should integrate with broader system recovery mechanisms:
By integrating file exception handling with these broader recovery mechanisms, COBOL programs can provide resilient and reliable file processing even in the face of various error conditions.
1. What is the purpose of the file status variable in COBOL?
2. Which file status code indicates a successful file operation in COBOL?
3. What is the file status code for "end of file reached" during a READ operation?
4. Which of the following is NOT a valid approach for handling file errors in COBOL?
5. What is the recommended practice for checking file status after operations?
Learn about operations for sequential files in COBOL.
Working with indexed files using key-based access.
General exception handling techniques in COBOL.
Understanding different file organizations in COBOL.
File declarations in the ENVIRONMENT DIVISION.