Using a Condition Handler

The following example shows you how to:

  1. Code a condition handler to handle the RPG 'out-of-bounds' error
  2. Register a condition handler
  3. Deregister a condition handler
  4. Code a *PSSR error subroutine.

The example consists of two procedures:

While SHOWERR is designed primarily to show how RPGHDLR works, the two procedures combined are also useful for determining 'how' ILE exception handling works. Both procedures write to QSYSPRT the 'actions' which occur as they are processed. You might want to modify these procedures in order to simulate other aspects of ILE exception handling which you would like to explore.

Figure 143 shows the source for the procedure RPGHDLR. The procedure defines three procedure parameters: an ILE condition token structure, a pointer to a communication area between SHOWERR and RPGHDLR, and a field to contain the possible actions, resume or percolate. (RPGHDLR does not promote any exceptions).

The basic logic of RPGHDLR is the following:

  1. Test to see if it is an out-of-bounds error by testing the message ID
  2. Return.
Figure 143. Source for Condition Handler for Out-of-Bounds Substring Error
      *=================================================================*
      * RPGHDLR: RPG exception handling procedure.                      *
      *          This procedure does the following:                     *
      *          Handles the exception if it is the RPG                 *
      *             out of bounds error (RNX0100)                       *
      *          otherwise                                              *
      *             percolates the exception                            *
      *          It also prints out what it has done.                   *
      *                                                                 *
      * Note:    This is the exception handling procedure for the       *
      *          SHOWERR procedure.                                     *
      *=================================================================*
     FQSYSPRT   O    F  132        PRINTER

     D RPGHDLR         PR
     D  Parm1                              LIKE(CondTok)
     D  Parm2                          *
     D  Parm3                        10I 0
     D  Parm4                              LIKE(CondTok)

      *-----------------------------------------------------------------*
      * Procedure parameters                                            *
      * 1. Input: Condition token structure                             *
      * 2. Input: Pointer to communication area containing              *
      *        a. A pointer to the PSDS of the procedure being handled  *
      *        b. An indicator telling whether a string error is valid  *
      * 3. Output: Code identifying actions to be performed on the      *
      *            exception                                            *
      * 4. Output: New condition if we decide to promote the            *
      *            condition.  Since this handler only resumes and      *
      *            percolates, we will ignore this parameter.           *
      *-----------------------------------------------------------------*
     D RPGHDLR         PI
     D  InCondTok                          LIKE(CondTok)
     D  pCommArea                      *
     D  Action                       10I 0
     D  OutCondTok                         LIKE(CondTok)
     D CondTok         DS                  BASED(pCondTok)
     D  MsgSev                        5I 0
     D  MsgNo                         2A
     D                                1A
     D  MsgPrefix                     3A
     D  MsgKey                        4A

     D CommArea        DS                  BASED(pCommArea)
     D   pPSDS                         *
     D   AllowError                   1N

     D PassedPSDS      DS                  BASED(pPSDS)
     D   ProcName              1     10

      *
      * Action codes are:
      *
     D Resume          C                   10
     D Percolate       C                   20

      *-----------------------------------------------------------------*
      *      Point to the input condition token                         *
      *-----------------------------------------------------------------*
     C                   EVAL      pCondTok = %ADDR(InCondTok)

      *-----------------------------------------------------------------*
      *      If substring error, then handle else percolate.            *
      *      Note that the message number value (MsgNo) is in hex.      *
      *-----------------------------------------------------------------*
     C                   EXCEPT
     C                   IF        MsgPrefix = 'RNX' AND
     C                             MsgNo     = X'0100' AND
     C                             AllowError = '1'
     C                   EXCEPT    Handling
     C                   EVAL      Action    = Resume
     C                   ELSE
     C                   EXCEPT    Perclating
     C                   EVAL      Action    = Percolate
     C                   ENDIF
     C                   RETURN

      *=================================================================*
      * Procedure Output                                                *
      *=================================================================*
     OQSYSPRT   E
     O                                              'HDLR: In Handler for '
     O                       ProcName
     OQSYSPRT   E            Handling
     O                                              'HDLR: Handling...'
     OQSYSPRT   E            Perclating
     O                                              'HDLR: Percolating...'

Figure 144 shows the source for the procedure SHOWERR, in which the condition handler RPGHDLR is registered.

The procedure parameters include a procedure pointer to RPGHDLR and a pointer to the communication area which contains a pointer to the module's PSDS and an indicator telling whether the out-of-bounds string error can be ignored. In addition, it requires a definition for the error-prone array ARR1, and identification of the parameter lists used by the ILE bindable APIs CEEHDLR and CEEHDLU.

The basic logic of the program is as follows:

  1. Register the handler RPGHDLR using the subroutine RegHndlr. This subroutine calls the CEEHDLR API, passing it the procedure pointer to RPGHDLR.
  2. Indicate to RPGHDLR that the out-of-bounds error is allowed, and then generate an out-of-bounds substring error, then set off the indicator so that RPGHDLR will not allow any unexpected out-of-bounds string errors.

    The handler RPGHDLR is automatically called. It handles the exception, and indicates that processing should resumes in the next machine instruction following the error. Note that the next machine instruction may not be at the beginning of the next RPG operation.

  3. Generate an out-of-bounds array error.

    Again, RPGHDLR is automatically called. However, this time it cannot handle the exception, and so it percolates it to the next exception handler associated with the procedure, namely, the *PSSR error subroutine.

    The *PSSR cancels the procedure.

  4. Unregister the condition handler RPGHDLR via a call to CEEHDLU.
  5. Return

As with the RPGHDLR procedure, SHOWERR writes to QSYSPRT to show what is occurring as it is processed.

Figure 144. Source for Registering a Condition Handler
      *=================================================================*
      * SHOWERR:       Show exception handling using a user-defined     *
      *                exception handler.                               *
      *=================================================================*
     FQSYSPRT   O    F  132        PRINTER

      *-----------------------------------------------------------------*
      * The following are the parameter definitions for the CEEHDLR     *
      * API.  The first is the procedure pointer to the                 *
      * procedure which will handle the exception.  The second          *
      * is a pointer to a communication area which will be passed       *
      * to the exception handling procedure.  In this example, this     *
      * area will contain a pointer to the PSDS of this module, and     *
      * an indicator telling whether an error is allowed.               *
      *                                                                 *
      * We should make sure this program (SHOWERR) does not ignore any  *
      * handled errors, so we will check the 'Error' indicator after    *
      * any operation that might cause an error that RPGHDLR will       *
      * "allow".  We will also check at the end of the program to make  *
      * sure we didn't miss any errors.                                 *
      *-----------------------------------------------------------------*
     D pConHdlr        S               *   PROCPTR
     D                                     INZ(%paddr('RPGHDLR'))

      *-----------------------------------------------------------------*
      * Communication area                                              *
      *-----------------------------------------------------------------*
     D CommArea        DS                  NOOPT
     D   pPsds                         *   INZ(%ADDR(DSPsds))
     D   AllowError                   1N   INZ('0')

      *-----------------------------------------------------------------*
      * PSDS                                                            *
      *-----------------------------------------------------------------*
     D DSPsds         SDS                  NOOPT
     D   ProcName        *PROC

      *-----------------------------------------------------------------*
      * Variables that will be used to cause errors                     *
      *-----------------------------------------------------------------*
     D Arr1            S             10A   DIM(5)
     D Num             S              5P 0

      *-----------------------------------------------------------------*
      * CEEHDLR Interface                                               *
      *-----------------------------------------------------------------*
     D CEEHDLR         PR
     D   pConHdlr                      *   PROCPTR
     D   CommArea                      *   CONST
     D   Feedback                    12A   OPTIONS(*OMIT)

      *-----------------------------------------------------------------*
      * CEEHDLU Interface                                               *
      *-----------------------------------------------------------------*
     D CEEHDLU         PR
     D   pConHdlr                      *   PROCPTR
     D   Feedback                    12A   OPTIONS(*OMIT)
      *-----------------------------------------------------------------*
      * Register the handler and generate errors                        *
      *-----------------------------------------------------------------*
     C                   EXSR      RegHndlr

      *-----------------------------------------------------------------*
      *      Generate a substring error                                 *
      *      This is an "allowed" error for this example (RPGHDLR       *
      *      handles the exception, allowing control to return to the   *
      *      next instruction after the error).                         *
      *      RPGHDLR will not allow the error unless the "AllowError"   *
      *      indicator is set on.  This ensures that if, for example,   *
      *      a SCAN operation is added to SHOWERR later, RPGHDLR will   *
      *      not by default allow it to have an error.                  *
      *-----------------------------------------------------------------*
     C                   Z-ADD     -1            Num
     C                   EVAL      AllowError = '1'
     C     Num           SUBST     'Hello'       Examp            10
     C                   EVAL      AllowError = '0'

      *-----------------------------------------------------------------*
      *      The exception was handled by the handler and control       *
      *      resumes here.                                              *
      *-----------------------------------------------------------------*
     C                   EXCEPT    ImBack

      *-----------------------------------------------------------------*
      *      Generate an array out of bounds error                      *
      *      This is not an "expected" error for this example.          *
      *-----------------------------------------------------------------*
     C                   Z-ADD     -1            Num
     C                   MOVE      Arr1(Num)     Arr1(Num)

      *-----------------------------------------------------------------*
      *      The exception was not handled by the handler, so,          *
      *      control does not return here.  The exception is            *
      *      percolated and control resumes in the *PSSR.               *
      *-----------------------------------------------------------------*

      *-----------------------------------------------------------------*
      *      Deregister the handler                                     *
      *      Note: If an exception occurs before the handler is         *
      *      deregistered, it will be automatically deregistered        *
      *      when the procedure is cancelled.                           *
      *-----------------------------------------------------------------*
     C                   EXSR      DeRegHndlr
     C                   SETON                                        LR

      *=================================================================*
      * RegHdlr - Call the API to register the Handler                  *
      *=================================================================*
     C     RegHndlr      BEGSR
     C                   CALLP     CEEHDLR(pConHdlr : %ADDR(CommArea) : *OMIT)
     C                   ENDSR

      *=================================================================*
      * DeRegHndlr - Call the API to unregister the Handler             *
      *=================================================================*
     C     DeRegHndlr    BEGSR
     C                   CALLP     CEEHDLU(pConHdlr : *OMIT)
     C                   ENDSR
      *=================================================================*
      * *PSSR: Error Subroutine for the procedure                       *
      *=================================================================*
     C     *PSSR         BEGSR
     C                   EXCEPT    InPssr
     C                   EXCEPT    Cancelling
      C                   ENDSR     '*CANCL'

      *=================================================================*
      * Procedure Output                                                *
      *=================================================================*
     OQSYSPRT   E            ImBack
     O                                              'I''m Back'
     OQSYSPRT   E            InPssr
     O                                              'In PSSR'
     OQSYSPRT   E            Cancelling
     O                                              'Cancelling...'

If you want to try these procedures, follow these steps:

  1. To create the procedure RPGHDLR, using the source shown in Figure 143, type:
    CRTRPGMOD MODULE(MYLIB/RPGHDLR)
  2. To create the procedure SHOWERR, using the source shown in Figure 144, type:
    CRTRPGMOD MODULE(MYLIB/SHOWERR)
  3. To create the program, ERRORTEST, type
    CRTPGM PGM(MYLIB/ERRORTEST) MODULE(SHOWERR RPGHDLR)
  4. To run the program ERRORTEST, type:
    OVRPRTF FILE(QSYSPRT) SHARE(*YES)
    CALL PGM(MYLIB/ERRORTEST)

    The output is shown below:

     HDLR: In Handler for SHOWERR
     HDLR: Handling...
     I'm Back
     HDLR: In Handler for SHOWERR
     HDLR: Percolating...
     In PSSR
     Cancelling...


[ Top of Page | Previous Page | Next Page | Contents | Index ]