Example in OPM RPG: Retrieving the HOLD parameter (exception message)

This example expects errors to be sent as escape messages.

Note: Read the Code license and disclaimer information for important legal information.

In the following program example, all the pieces have been put together with an RPG program that accesses the hold on job queue information from a job description. A message is sent for the value found. To make the RPG program more general purpose, two parameters for the job description (JOBD) name and library (JOBDL) name are passed to it, as shown at (5). The program example, which is named JOBDAPI (this program name is also used in other examples in this chapter), does not handle errors. Any errors that are received are returned as exception messages.

     I*****************************************************************
     I*****************************************************************
     I*
     I*Program Name: JOBDAPI
     I*
     I*Language:  OPM RPG
     I*
     I*Descriptive Name:  Job Description
     I*
     I*Description:  This example expects errors to be sent as escape
     I*              messages.
     I*
     I*Header Files Included: QUSEC - Error Code Parameter
     I*                       QWDRJOBD - Retrieve Job Description API
     I*
     I*****************************************************************
     I*****************************************************************
     I*
     I* Error Code Parameter Include for the APIs
     I*
     I/COPY QSYSINC/QRPGSRC,QUSEC
     I*
     I* Retrieve Job Description API Include
     I*
     I/COPY QSYSINC/QRPGSRC,QWDRJOBD          (1)
     I*
     I* Command String Data Structure
     I*
     ICMDSTR      DS
     I I            'SNDMSG MSG(''HOLD -      1  26 CMD1
     I              'value is '
     I                                       27  36 HOLD
     I I            ''') TOUSR(QPGMR)'       37  51 CMD2
     I*
     I* Miscellaneous Data Structure
     I*
     I            DS                                      
     I*                                (2)
     I I            390                   B   1   40RCVLEN 
     I I            'JOBD0100'                5  12 FORMAT 
     I*                (3)
     C*
     C* Beginning of Mainline
     C*
     C* Two parameters are being passed into this program.
     C*
     C           *ENTRY    PLIST   (5)
     C                     PARM           JOBD   10
     C                     PARM           JOBDL  10
     C*
     C* Move the two parameters passed into LFNAM.
     C*
     C           JOBD      CAT  JOBDL     LFNAM  20   (6)
     C* Error code bytes provided is set to 0
     C*
     C                     Z-ADD0         QUSBNB    (4)
     C*                                           
     C* Instead of specifying 'QWCRJOBD', I could have used the
     C* constant QWDBGB that was defined in the QWDRJOBD include.
     C*
     C                     CALL 'QWDRJOBD'
     C                     PARM           QWDBH            Receiver Var.
     C                     PARM           RCVLEN           Length RCVVAR
     C                     PARM           FORMAT           Format Name
     C                     PARM           LFNAM            Qual. Job Desc
     C                     PARM           QUSBN            Error Code
     C*
     C                     MOVELQWDBHN    HOLD
     C*
     C* Let's tell everyone what the hold value was for this jobd.
     C*
     C                     Z-ADD51        LENSTR 155
     C                     CALL 'QCMDEXC'
     C                     PARM           CMDSTR
     C                     PARM           LENSTR
     C*
     C                     SETON                     LR
     C                     RETRN
     C*
     C* End of MAINLINE
     C*

The program declares the variables to be used. The QWDBH variable is length 390 as shown by (2).

In the example, the program places a value of JOBD0100 in the format variable. A literal could have been used instead for those languages that support a literal on a call, as shown at (5). The program generates the qualified name of the job description (JOBD) by concatenating the simple name and the library qualifier, as shown at (6). A 20-character variable must be used, and the simple name must begin in byte 1 with the library qualifier in byte 11. Because CAT is used, a simple concatenation of two 10-byte variables occurs so that the names are in the correct place for the LFNAM parameter.

The QWDRJOBD API is called with the correct parameter list. The API uses the parameter list and accesses the job description specified. The API extracts the values from the internal object form and places them in a data structure that matches the JOBD0100 format. The API then returns with the data structure placed in variable QWDBH, which is located in member QWDRJOBD in the QSYSINC library.

The output is similar to the following:

+--------------------------------------------------------------------------------+
|                                                                                |
|                                                                                |
|                                Display Messages                                |
|                                                                                |
|                                                       System:   GENSYS90       |
| Queue . . . . . :   QPGMR                   Program . . . . :   *DSPMSG        |
|   Library . . . :     QUSRSYS                 Library . . . :                  |
| Severity  . . . :   00                      Delivery  . . . :   *HOLD          |
| Type reply (if required), press Enter.                                         |
|   From  . . . :   SMITH          07/23/94   10:25:14                           |
|   HOLD value is *NO                                                            |
|                                                                                |
+--------------------------------------------------------------------------------+

The API does not need to be called each time that you want a separate field because all fields are returned that would fit within the size indicated by the length of receiver variable (RCVLEN) parameter. You can run the program against the QBATCH job description in library QGPL by using the following call statement:

CALL JOBDAPI PARM(QBATCH QGPL)

If QGPL is on the library list, you can run the program against the QBATCH job description by using the following call statement:

CALL JOBDAPI PARM(QBATCH *LIBL)

You can run the program on one of your own job descriptions or on a test job description where you have specified HOLD(*YES).

Example in OPM RPG: Handling error conditions

For this example, assume that the XYZ job description does not exist:

CALL JOBDAPI PARM(XYZ *LIBL)

You probably will receive the inquiry message CPA0701 that states an unmonitored exception (CPF9801) has occurred and offers several possible replies. At this point, you would enter C for Cancel and press the Enter key.

If you displayed the low-level messages, you would see the following: CPF9801 (Object not found), followed by the inquiry message (CPA0701), followed by your reply.

When you specify the error code parameter as zero, you are specifying that exceptions be sent as escape messages. You can code the RPG program so that any errors on the call set the indicator 01 to on, as shown at (10). This causes a different path to be taken in the code.

For RPG, the CALL operation specifies the error indicator. Based on whether the error indicator is on or off, a set of instructions can be processed. The API must receive an error code parameter that consists of a binary 4 field with a value of binary zeros, as shown at (11)). The message ID can be accessed from the program-status data structure. You would define this as follows:

     I* Program status DS ((12))
     IPGMSTS     SDS
     I                                       40  46 MSGIDD

If you are going to do something about an error condition, you must test for an error condition in RPG:

Because you must test for some condition (one of the error messages in Error Messages), no great difference exists in how you handle error conditions in RPG. The error-code data structure is a little more straightforward (the program-status data structure is not used). The only disadvantage of the error-code data structure is that the escape message that occurred was removed from the job log.

The following program shows how to code for an error condition, test for that condition, and send a message to the QPGMR message queue if the condition occurs:

     I*****************************************************************
     I*****************************************************************
     I*
     I*Program Name: JOBDAPI
     I*
     I*Language:  OPM RPG
     I*
     I*Descriptive Name:  Get Job Description
     I*
     I*Description:  This program handles any errors that are
     I*              returned
     I*
     I*Header Files Included: QUSEC - Error Code Parameter
     I*                       QWDRJOBD - Retrieve Job Description API
     I*
     I*****************************************************************
     I*****************************************************************
     I*
     I* Error Code Parameter Include for the APIs
     I*
     I/COPY QSYSINC/QRPGSRC,QUSEC
     I*
     I* Retrieve Job Description API Include
     I*
     I/COPY QSYSINC/QRPGSRC,QWDRJOBD
     I* Program status DS
     IPGMSTS     SDS   (12)
     I                                       40  46 MSGIDD
     I*
     I* Command String Data Structure
     I*
     ICMDSTR      DS
     I I            'SNDMSG MSG(''HOLD -      1  26 CMD1
     I              'value is '
     I                                       27  36 HOLD
     I I            ''') TOUSR(QPGMR)'       37  51 CMD2
     I*
     IMSG3        DS
     I I            'SNDMSG MSG(''No such-    1  35 MSG3A
     I              ' *JOBD exists'') '
     I I            'TOUSR(QPGMR)'           36  47 MSG3B
     I*
     I* Miscellaneous Data Structure
     I*
     I            DS
     I I            390                   B   1   40RCVLEN
     I I            'JOBD0100'                5  12 FORMAT
     C*
     C* Beginning of Mainline
     C*
     C* Two parameters are being passed into this program.
     C*
     C           *ENTRY    PLIST
     C                     PARM           JOBD   10
     C                     PARM           JOBDL  10
     C*
     C* Move the two parameters passed into LFNAM.
     C*
     C           JOBD      CAT  JOBDL     LFNAM  20
     C* Error code bytes provided is set to 0
     C*
     C                     Z-ADD0         QUSBNB (11)
     C*                                              
     C* Instead of specifying 'QWCRJOBD', I could have used the
     C* constant QWDBGB that was defined in the QWDRJOBD include.
     C*                          
     C                     CALL 'QWDRJOBD'             01 (10)
     C                     PARM           QWDBH            Receiver Var.
     C                     PARM           RCVLEN           Length RCVVAR
     C                     PARM           FORMAT           Format Name
     C                     PARM           LFNAM            Qual. Job Desc
     C                     PARM           QUSBN            Error Code
     C   01                EXSR ERROR                      Error Subroutine
     C*
     C  N01                MOVELQWDBHN    HOLD
     C*
     C* Let's tell everyone what the hold value was for this job.
     C*
     C  N01                Z-ADD51        LENSTR 155
     C  N01                CALL 'QCMDEXC'
     C                     PARM           CMDSTR
     C                     PARM           LENSTR
     C*
     C                     SETON                     LR
     C                     RETRN
     C*
     C* End of MAINLINE
     C*
     C* Subroutine to handle errors received on the CALL
     C*
     C           ERROR     BEGSR
     C           MSGIDD    IFEQ 'CPF9801'
     C*
     C* Process errors returned from the API.
     C*
     C                     Z-ADD47        LENSTR 155
     C                     CALL 'QCMDEXC'
     C                     PARM           MSG3
     C                     PARM           LENSTR
     C                     END
     C                     ENDSR

If the CPF9801 exception occurs, your program sends a message to the QPGMR message queue as shown in the following display:

+--------------------------------------------------------------------------------+
|                                                                                |
|                                                                                |
|                                Display Messages                                |
|                                                                                |
|                                                                                |
|                                                       System:   GENSYS90       |
| Queue . . . . . :   QPGMR                   Program . . . . :   *DSPMSG        |
|   Library . . . :     QUSRSYS                 Library . . . :                  |
| Severity  . . . :   00                      Delivery  . . . :   *HOLD          |
| Type reply (if required), press Enter.                                         |
|   From  . . . :   SMITH          07/25/94   11:10:12                           |
|   No such *JOBD exists                                                         |
|                                                                                |
+--------------------------------------------------------------------------------+

If another exception occurs (for example, a library name that is not valid), you do not receive an indication that an error occurred because of the way the error subroutine is currently coded.

In addition, you can use the Message Handling APIs to receive the messages sent to your program message queue.

The call to the API fails if you specify a valid job description but use a library qualifier such as *ALLUSR. The value *ALLUSR is not supported by the description of the required parameter group.

See the following for the same example in different languages:

Related concepts
API description
Related reference
Error Messages
Example in ILE COBOL: Retrieving the HOLD parameter (exception message)
Example in ILE C: Retrieving the HOLD parameter (exception message)
Example in ILE RPG: Retrieving the HOLD parameter (exception message)
Example in OPM RPG: Retrieving the HOLD parameter (error code structure)
Example in OPM RPG: Accessing the HOLD attribute