Monitoring for Exceptions

The monitor group performs conditional error handling based on the status code. It consists of: a MONITOR statement, one or more ON-ERROR groups, and an ENDMON statement. After the MONITOR statement, control passes to the next statement. The monitor block consists of all the statements from the MONITOR statement to |the first ON-ERROR statement. If an error occurs when the monitor block is processed, control is passed to the appropriate ON-ERROR group.

      * Fixed format example:
      * Monitor block used to trap error on date operations:

     C                   MONITOR
     C                   EVAL      P$ERR = 'OK'
     C                   IF        P$INCR = 0
     C                   EVAL      I = 3
     C                   ELSE
     C                   EVAL      I = P$INCR
     C                   ENDIF
     C                   Time                    $$DATE
     C     $$DATE        ADDDUR    I:*DAYS       $$NextDate
     C     $$DATE        SUBDUR    I:*DAYS       $$PastDate
     C     *ISO          MOVE      $$DATE        P$CRDTE
     C     *ISO          MOVE      $$PASTDATE    P$PRDTE
     C     *ISO          MOVE      $$NEXTDATE    P$NXDTE
     C                   ON-ERROR
     C                   EVAL      P$ERR = 'MIS0043'
     C                   ENDMON

      * Monitor block used to trap error on file operations:
      * In this instance the monitor is looking to handle a file error
      * code 1218 (record lock), or 1211 (file not open)

     C                   MONITOR
     C     ITMKEY        CHAIN     NTLQTYPF
     C                   IF        %found(NTLQTYPF)
     C                   MOVE      W$QTY         W$NEWV
     C                   MOVE      NQQOH         W$OLDV
     C                   IF        W$NEWV <> W$OLDV
     C                   EVAL      NQQOH = W$QTY
     C                   UPDATE    RNTLQTY
     C                   ENDIF
     C                   ENDIF
     C                   ON-ERROR  1211
     C                   EXSR      @EXIT
     C                   ON-ERROR  1218
     C                   CALL      'MIS510CL'                           75
     C                   PARM                    JOBNAM
     C                   PARM                    JOBNBR
     C                   PARM                    DBFMBR
     C                   PARM                    DBFLIB
     C                   ENDMON

The monitor group should not include branching operations, but the ON-ERROR group does. In the example below the ON-ERROR group is set to react to any program error, error status codes 00100 to 00999. The second example demonstrates the error group set to react to any *FILE errors, while attempting to open DB files for processing.

             CALLP WrtStsChg( hdrprj :                                   
                              hdrsub :                                   
                              p$usr  :                                   
                              p$sts  :                                   
                              p$pna  :                                   
                              prgnam );                                  
          ON-ERROR *PROGRAM;                                                         
             EXSR @exit;                                                    

c002      MONITOR;
 |           OPEN ADMHDRL1;
 |           OPEN ADMDETPF;
 |           OPEN GST010;
 |        ON-ERROR *file;
 |           EXSR @Exit;
c002      ENDMON;

Here is a trick using MONITOR to bypass a record lock. In this example the program is reading a file that is an update file. If a record lock occurs, the ON-ERROR segment of the MONITOR reads the record without locking and continues with the loop logic, reading the next record. This of course is based on the assumption the process can continue without negative consequences as a result of not updating the record.

0221.00     SETLL *loval  GPORTAFF;           
0222.00     DOU %eof(GPORTAFF);               
0224.00     MONITOR;                          
0226.00     READ GPORTAFF;                    
0228.00     IF not %eof(GPORTAFF);

0440.00     ON-ERROR *FILE;    
0441.00       READ(N) GPORTAFF;
0442.00     ENDMON;            
0444.00     ENDDO;