MONITOR blocks provide structured exception handling, similar to try-catch in Java. When an exception occurs in the protected block, control passes to the first matching ON-EXCP handler (by message ID), then to the first matching ON-ERROR handler (by status code).
DCL-S result PACKED(5:0);
DCL-S divisor PACKED(5:0) INZ(0);
MONITOR;
result = 100 / divisor; // Division by zero
ON-ERROR 102; // Catch divide-by-zero (status 102)
result = 0;
ON-ERROR; // Catch-all for any other error
result = -1;
ENDMON;
Key behaviors:
- First-match semantics: ON-ERROR clauses are evaluated in declaration order. The first matching handler executes; subsequent handlers are skipped.
- Catch-all:
ON-ERROR;(no codes) orON-ERROR *ALL;catches any error. %STATUS: Inside an ON-ERROR handler,%STATUSreturns the RPG status code of the trapped error.- Propagation: If no ON-ERROR matches, the exception propagates to the next enclosing MONITOR or causes program termination.
- Nested MONITORs: Inner MONITOR blocks are evaluated before outer blocks.
- (E) extender interaction: If an operation uses the (E) extender, its errors are handled by the extender, not by an enclosing MONITOR block.
Status code groupings:
| Syntax | Matches |
|---|---|
ON-ERROR 102; |
Specific status code (divide by zero) |
ON-ERROR 102:121:122; |
Any of the listed codes |
ON-ERROR *PROGRAM; |
All program status codes (00100 - 00999) |
ON-ERROR *FILE; |
All file status codes (01000 - 09999) |
ON-ERROR *ALL; |
All errors (equivalent to bare ON-ERROR;) |
ON-ERROR 102 : *FILE; |
Specific codes mixed with groupings |
Common program status codes:
| Code | Description |
|---|---|
| 00100 | String operation error |
| 00102 | Divide by zero |
| 00121 | Array index not valid |
| 00122 | OCCUR value out of range |
| 00222 | Pointer or parameter error |
Fixed-format support:
MONITOR, ON-ERROR, and ENDMON are supported in both free-format and fixed-format C-specs. In fixed-format, ON-ERROR status codes are specified in Factor 2:
C MONITOR
C ...statements...
C ON-ERROR 00122
C ...handler...
C ENDMON
ON-EXCP - message-ID-based exception handling (free-format only):
ON-EXCP catches exceptions by message ID (e.g. MCH1211, CPF9898) rather than by numeric status code. ON-EXCP clauses must precede any ON-ERROR clauses in the MONITOR group.
DCL-S x PACKED(5:0) INZ(10);
DCL-S y PACKED(5:0) INZ(0);
DCL-S result CHAR(30);
MONITOR;
x = x / y; // Divide by zero
ON-EXCP 'MCH1211'; // Catch by message ID
result = 'Division by zero';
ON-EXCP 'CPF9898'; // Catch generic escape
result = 'Generic escape';
ON-ERROR; // Catch-all by status code
result = 'Other error';
ENDMON;
- Ordering: ON-EXCP clauses must come before ON-ERROR clauses.
- Multiple message IDs:
ON-EXCP 'MCH1211' : 'MCH1202';catches any of the listed IDs. - First-match semantics: The first matching ON-EXCP or ON-ERROR handler wins.
- No wildcarding: Message IDs must match exactly (no prefix/range matching).
- Scope: ON-EXCP catches escape messages from operations in the MONITOR body, including messages from called procedures.
SND-MSG *ESCAPEwithin the same procedure sends the escape to the caller and is not caught by a local ON-EXCP. - Known message IDs on JVM:
MCH1211(divide by zero),CPF9898(SND-MSG *ESCAPE). - Operation extender: The
(C)extender (ON-EXCP(C)) restricts the handler to exceptions sent directly to the current procedure. Without(C), the handler also catches unhandled exceptions that percolated from called procedures. - Fixed-format: ON-EXCP is free-format only - no fixed-format C-spec equivalent exists.