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.
Figure 1 shows an example of a program error subroutine in a 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.
*-----------------------------------------------------------------*
* 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
*-----------------------------------------------------------------*
* 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