On 06-Jun-2016 12:20 -0500, MichaelQuigley wrote:
On 03-Jun-2016 12:33 -0500, Richard Schoen wrote:
On 02-Jun-2016 18:34 -0500, Vinay Gavankar wrote:
I am an occasional Cobol user, and was wondering how I would go
about trapping an error returned by the QSNDDTAQ API called from
a Cobol program.

We want to trap the condition when Data Queue is full (CPF950A)
and go in a DLYW before trying again.

I think calling a CL program from the Cobol to call the API,
instead of calling the API directly might work, but I have been
told to check if it is possible to do without adding a new CL
program call.

I tried ON EXCEPTION clause, but that seems to trap only errors
on the Call command (program not found, parameter mismatch etc),
so does not work in this case.

Any suggestions, guidance will be greatly appreciated.

Do it with a CL or RPG program call if you need to trap specific
CPF errors.

That's part of the equation. There's no IBM provided command to send
dtaq entries. So you can't just do a MONMSG.

The ability to effect Monitor Message (MONMSG) is not unique to a specific command\request vs a generic CALL command\request. The effect of messaging for the CALL is no different; i.e. the MSGID(CPF950A) is functional for monitoring the Escape message CPF950A send from QSNDDTAQ irrespective the method of invocation being the Command Processing Program (CPP) for a Command (CMD) or the Program (PGM) named on a CALL.


This can be done in COBOL using the message APIs, but it is easier in
CL. The basic flow is 1) Send a message and save the key of the
message sent. 2) Call the API. 3) Then walk through the messages
using RCVMSG starting with the key from step 1.

Because the Send Data Queue (QSNDDTAQ) API sends the message to the /previous/ call stack entry, the invoker is the recipient, so the following coding [which presumably reflects the methodology for finding messages that were left on an inactive program message queue] is unnecessarily complex. One need only code the MONMSG and optionally a Receive Message (RCVMSG) and\or some other handling in response to the monitored exception.


Here's an example of the coding: (I've hardcoded the dataq and
library names.)

PGM PARM(&DATA &DATALEN)

DCL VAR(&FOREVER) TYPE(*LGL)
DCL VAR(&STRKEYVAR) TYPE(*CHAR) LEN(4)
DCL VAR(&KEYVAR) TYPE(*CHAR) LEN(4)
DCL VAR(&LSTKEYVAR) TYPE(*CHAR) LEN(4)
DCL VAR(&DATA) TYPE(*CHAR) LEN(200)
DCL VAR(&DATALEN) TYPE(*DEC) LEN(5 0)

DCL VAR(&MSGID) TYPE(*CHAR) LEN(7)

SNDPGMMSG MSG('Temporary message anchor') TOPGMQ(*SAME) +
KEYVAR(&KEYVAR)

CHGVAR VAR(&STRKEYVAR) VALUE(&KEYVAR)

CALL PGM(QSNDDTA) PARM(DATAQ DATAQLIB &DATALEN &DATA)

DOUNTIL COND(&FOREVER)
/* Use the previous message key to locate next message */
CHGVAR VAR(&LSTKEYVAR) VALUE(&KEYVAR)
RCVMSG MSGTYPE(*NEXT) MSGKEY(&LSTKEYVAR) +
KEYVAR(&KEYVAR) MSGID(&MSGID)
/* I'm leaving the message on the queue RMV(*NO) */
/* -- The default is to remove it RMV(*YES) */
IF COND(&MSGID *EQ 'CPF950A') THEN(DO)
PROCESSING {Do whatever you need done here}
/* Since I've handled the message, I'm removing it now. */
RMVMSG MSGKEY(&KEYVAR)
LEAVE
ENDDO
ENDDO

/* Clean up the temporary anchor message */
RMVMSG MSGKEY(&STRKEYVAR)

ENDPGM


Of course you can tailor the basic logic as needed. Another option
would be to set up a command that did the QSNDDTAQ and see if you can
do a MONMSG for them or write the command processing program to send
escape messages so they can be monitored.

Again, there is nothing special\unique about using a CALL vs using a CPP for a [user-created] CMD.

The following test program exhibits the ability of a CLP to monitor for the CPF950A for the preceding CALL to the API; the following source compiled as CL program SNDTOFULLQ, run interactively per the request CALL SNDTOFULLQ issued from a command-line, the program will issue a request to DSPJOBLOG to reveal [after F10=Display Detailed Messages and F18=Bottom are pressed] that the last message prior to the DSPJOBLOG request message, was the Escape msg CPF950A sent F/QSNDDTAQ and sent T/SNDTOFULLQ with first level text "Storage limit exceeded for data queue FILLED_UP in QTEMP.":


dcl &dta *char 32 value('some text to enqueue')
dcl &dtalen *dec ( 5 00) value(64512)
dcl &err *lgl value('0')
crtdtaq qtemp/filled_up type(*std) SENDERID(*NO) +
MAXLEN(64512) FORCE(*NO) SEQ(*FIFO) SIZE(*MAX16MB 4) +
AUTORCL(*NO) TEXT('test for dtaq full msg CPF950A')
monmsg cpf9870
dowhile (*not &err)
call qsys/qsnddtaq parm(filled_up qtemp &dtalen &dta )
monmsg cpf950A exec(do)
chgvar &err '1'
dspjoblog
enddo
enddo



As an Amazon Associate we earn from qualifying purchases.

This thread ...

Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2022 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.