On 5/23/2017 7:12 PM, Nathan Andelin wrote:
On Fri, May 19, 2017 at 10:31 AM, Buck Calabro <kc2hiz@xxxxxxxxx> wrote:
I invoke QMHRCVPM/RCVMSG *LAST and subsequently *PRV with the message
key got from *LAST.  Is there another way for the system to raise an
exception message?  Or another way for a program to do something with
them?  I'm specifically thinking about 'number of possible variations'
and drawing a blank.
Buck, it might help if you could post a code sample. 
This is brute force - the loops unrolled and everything laid bare
specifically to show the flow of messages.  This is NOT a good idea for
production code; it's expressly intended as a learning exercise.
Ironically, the error handling is non-existent.  Apologies for the RPG
code; I didn't have time to do it in CL.
Regardless of HLL, the process is: start with *LAST *BLANKS; that yields
the MSGKEY of the *LAST (most recent) message,  Having that message key,
use *PRV MSGKEY to go backward in time.
As the program goes backward, it finds messages it wants to handle.  Set
a flag for each 'class' of error to be handled - this code has only one
class (RI violation).  Note that one concept of 'handled' is 'ignore
this message' - think 'deleting a file that's already been deleted' for
just one example of this message class.
All the other messages get a generic handler which usually results in a
post-mortem dump so that the technical staff can figure out what went
casters up without having to personally step through the code in debug.
The goals:
1) Never, ever let a program wait for a reply.
2) Tell the end user if something unrecoverable happened, even if it's
as vague as 'can't process transaction now'.
3) Tell the technology staff if an actionable event occurred.
...
  if %error();
    fileStatus = %status();
  endif;
...
  select;
    when fileStatus = 01022;   // RI violation
      exsr status01022;
    other;
      // here is where the generic error handling goes
  endsl;
...
begsr status01022;
  clear cpf502d;
  // several messages may get sent
  // receive from the newest to the oldest
  // the newest has a special setup
  // for CPF502D, the sequence is:
  // the default reply, 'C',
  // then the CPF502D
  msgType = '*LAST';
  msgkey = *blanks;
  rcvPgmMsg(rcvm0200: messageInfoLen: fmtName:
            callStackEntry: callStackCounter:
            msgType: msgKey: waitTime: msgAction: qusec);
  // msgkey not found
  if qusec.errmsgID = 'CPF2410';
    leavesr;
  endif;
  // message received
  if qusec.errMsgId <> *blanks;
    dump(a) 'unknown RCVMSG errmsgid c';
    leavesr;
  endif;
  // CPF502D- RI violation
  msgType = '*PRV';
  msgKey = rcvm0200.msgKey;
  rcvPgmMsg(rcvm0200: messageInfoLen: fmtName:
            callStackEntry: callStackCounter:
            msgType: msgKey: waitTime: msgAction: qusec);
  // msgkey not found
  if qusec.errmsgID = 'CPF2410';
    leavesr;
  endif;
  // message received
  if qusec.errMsgId <> *blanks;
    dump(a) 'unknown RCVMSG errmsgid 502d';
    leavesr;
  endif;
  // RI violation
  if rcvm0200.msgid = MSG_RI_VIOLATION;
    cpf502d = rcvm0200.msgdata;
    exsr friendlyUI;
  endif;
endsr;
// issue user friendly message and position cursor appropriately
begsr friendlyUI;
  // first, get the RI pseudo message ID.
  // the constraint name is formatted to embed a constant we can CHAIN with
  // "nnnnn ADDRESS table blah blah"
  // the actual name includes those double quotes!
  if rcvm0200.msgid = MSG_RI_VIOLATION;
    pseudoMessageID = %subst(cpf502d.constraint: 2: 5);
    if pseudoMessageID <> *blanks;
      // instead of a CHAIN, brute force it.
      // again, this is a technology demonstrator
      select;
        when pseudoMessageId = '00005';
          messageData = 'Check Address ID please';
          eval *in31 = *on;  // position cursor
        when pseudoMessageId = '00006';
          messageData = 'Check Sales Region ID please';
          eval *in32 = *on;  // position cursor
        when pseudoMessageId = '00007';
          messageData = 'Check Marketing Manager ID please';
          eval *in33 = *on;  // position cursor
        other;
          messageData = 'Call IT at 555-1212 and tell them to check the
logs for TEST_RI';
          dump(a) 'pseudoMessageKey';
      endsl;
      // before we send our friendly message, remove those
system-generated messages
      clrPgmMsg('*': 0: *blanks: '*ALL': qmhErr);
      // deliver the friendly message
      sndPgmMsg('CPF9898': messageFile: messageData:
                 50: '*INFO': '*':
                 0: wmsgk: qmhErr);
    endif;
  endif;
endsr;
As an Amazon Associate we earn from qualifying purchases.