Using a Program Error Subroutine

To handle a program error or exception you can write a program error subroutine (*PSSR). When a program error occurs:
  1. The program status data structure is updated.
  2. If an indicator is not specified in positions 73 and 74 for the operation code, the error is handled and control is transferred to the *PSSR.

    You can explicitly transfer control to a program error subroutine after a file error by specifying *PSSR after the keyword INFSR on the File Description specifications.

You can code a *PSSR for any (or all) procedures in the module. Each *PSSR is local to the procedure in which it is coded.

To add a *PSSR error subroutine to your program, you do the following steps:
  1. Optionally identify the program status data structure (PSDS) by specifying an S in position 23 of the definition specification.
  2. Enter a BEGSR operation with a Factor 1 entry of *PSSR.
  3. Identify a return point, if any, and code it on the ENDSR operation in the subroutine. For subprocedures, factor 2 must be blank. For a discussion of the valid entries for Factor 2, see Specifying a Return Point in the ENDSR Operation.
  4. Code the rest of the program error subroutine. Any of the ILE RPG compiler operations can be used in the program error subroutine. The ENDSR operation must be the last specification for the program error subroutine.

Figure 1 shows an example of a program error subroutine in a cycle-main procedure.

Figure 1. Example of *PSSR Subroutine in Cycle-Main Procedure
      *-----------------------------------------------------------------*
      *  Define relevant parts of program status data structure         *
      *-----------------------------------------------------------------*
     D Psds           SDS
     D  Loc              *ROUTINE
     D  Err              *STATUS
     D  Parms            *PARMS
     D  Name             *PROC
      *-----------------------------------------------------------------*
      *  BODY OF CODE GOES HERE
      *  An error occurs when division by zero takes place.
      *  Control is passed to the *PSSR subroutine.
      *-----------------------------------------------------------------*
      *=================================================================*
      * *PSSR: Error Subroutine for the main procedure.  We check for a
      *        division by zero error, by checking if the status is
      *        102.  If it is, we add 1 to the divisor and continue
      *        by moving *GETIN to ReturnPt.
      *=================================================================*
     C     *PSSR         BEGSR
     C                   IF        Err = 102
     C                   ADD       1             Divisor
     C                   MOVE      '*GETIN'      ReturnPt          6
      *-----------------------------------------------------------------*
      *        An unexpected error has occurred, and so we move
      *        *CANCL to ReturnPt to end the procedure.
      *-----------------------------------------------------------------*
     C                   ELSE
     C                   MOVE      '*CANCL'      ReturnPt
     C                   ENDIF
     C                   ENDSR     ReturnPt

The program-status data structure is defined on the Definition specifications. The predefined subfields *STATUS, *ROUTINE, *PARMS, and *PROGRAM are specified, and names are assigned to the subfields.

The *PSSR error subroutine is coded on the calculation specifications. If a program error occurs, ILE RPG passes control to the *PSSR error subroutine. The subroutine checks to determine if the exception was caused by a divide operation in which the divisor is zero. If it was, 1 is added to the divisor (Divisor), and the literal ‘*DETC’ is moved to the field ReturnPt, to indicate that the program should resume processing at the beginning of the detail calculations routine

If the exception was not a divide by zero, the literal ‘*CANCL’ is moved into the ReturnPt field, and the procedure ends.

Figure 2 and Figure 3 show how you would code similar program error subroutines in a subprocedure. In one example, you code a GOTO and in the other you code a RETURN operation.

Figure 2. Example of Subprocedure *PSSR Subroutine with GOTO
      *-----------------------------------------------------------------*
      *  Start of subprocedure definition
      *-----------------------------------------------------------------*
     P SubProc         B
     D SubProc         PI             5P 0
      ...
      *-----------------------------------------------------------------*
      *  Body of code goes here including recovery code.
      *-----------------------------------------------------------------*
     C      TryAgain     TAG
     C      X            DIV       Divisor       Result
     C                   Return    Result
      *-----------------------------------------------------------------*
      *  An error occurs when division by zero takes place.
      *  Control is passed to the *PSSR subroutine.
      *-----------------------------------------------------------------*
     C     *PSSR         BEGSR
      *-----------------------------------------------------------------*
      * If this is a divide-by-zero error, add 1 to the divisor
      * and try again
      *-----------------------------------------------------------------*
     C                   IF        Err = 102
     C                   ADD       1             Divisor
     C                   GOTO      TryAgain
     C                   ENDIF
      *-----------------------------------------------------------------*
      * If control reaches ENDSR, the procedure will fail
      *-----------------------------------------------------------------*
     C                   ENDSR
     P                 E
Figure 3. Example of Subprocedure *PSSR Subroutine with RETURN
      *-----------------------------------------------------------------*
      *  Start of subprocedure definition
      *-----------------------------------------------------------------*
     P SubProc         B
     D SubProc         PI             5P 0
      ...
      *-----------------------------------------------------------------*
      *  Body of code goes here including division operation.
      *-----------------------------------------------------------------*
     C      X            DIV       Divisor       Result
     C                   Return    Result
      *-----------------------------------------------------------------*
      *  An error occurs when division by zero takes place.
      *  Control is passed to the *PSSR subroutine.
      *-----------------------------------------------------------------*
     C     *PSSR         BEGSR
      *-----------------------------------------------------------------*
      * If this is a divide-by-zero error, return 0 from the subprocedure
      *-----------------------------------------------------------------*
     C                   IF        Err = 102
     C                   RETURN    0
     C                   ENDIF
      *-----------------------------------------------------------------*
      * If control reaches ENDSR, the procedure will fail
      *-----------------------------------------------------------------*
     C                   ENDSR
     P                 E