23
Tue, Apr
0 New Articles

The API Corner: Removing Error Messages from the Job Log

APIs
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

Now that we've figured out how to receive them, how do we remove them if we want to?

 

Last month, in "The API Corner: More on Message Handling," we looked at how to receive diagnostic messages (such as CPF3213 – Members for file more than maximum allowed) using the Receive Program Message (QMHRCVPM) API. The diagnostic message was needed in order to determine the underlying cause of an escape message (in our example, CPF7306 – Member not added) and then take the appropriate corrective action. The recovery action for CPF3213 was to change the file's MAXMBRS attribute to *NOMAX by using the Change Physical File (CHGPF) command and then adding the required member using the Add Physical File Member (ADDPFM) command. Both of these commands were run by the RPG application program using the Process Commands (QCAPCMD) API. However, after successfully adding the member, we noticed that the job log still contained the CPF3213 diagnostic message along with the two completion messages (CPC7303 – File SOMEFILE in library xxxxxx changed and CPC7305 – Member yyyyyy added to file SOMEFILE in xxxxxx) that were related to our handling of the initial CPF7306 error. Today's "API Corner" article looks at various options of how we can, if we want to, remove these messages.

 

In earlier articles, such as "The API Corner: Automating Recovery (or Keeping the Help Desk Out of the Loop)," we used the Remove Program Message (QMHRMVPM) API, documented here, but we never really looked at the API in any detail. The QMHRMVPM API has five required parameters and several optional parameter groups. These are the five required parameters (and the only parameters that we will be using today):

 

1

Call stack entry

Input

Char(*) or Pointer

2

Call stack counter

Input

Binary(4)

3

Message key

Input

Char(4)

4

Messages to remove

Input

Char(10)

5

Error code

I/O

Char(*)

 

In the previously mentioned Automating Recovery article, we prototyped these five required parameters this way:

 

dRmvMsg           pr                  extpgm('QSYS/QMHRMVPM')    

d CallStackEntry             65535    const options(*varsize)    

d CallStackCntr                 10i 0 const                      

d MsgKey                         4    const                      

d MsgsToRmv                     10    const                      

d QUSEC                               likeds(QUSEC)              

 

And then we called the API using this statement:

 

RmvMsg('*' :0 :' ' :'*ALL' :QUSEC);                   

 

The first two parameters, Call stack entry and Call stack counter, work together to identify where the message (or messages) to be removed can be found. The special value '*' for Call stack entry specifies that the base call stack entry to use for locating the message(s) is the caller of the QMHRMVPM API. The Call stack counter parameter provides a counter, relative to the Call stack entry parameter value, of where the message(s) can be found. A value of 0 for Call stack counter simply indicates that the Call stack entry parameter value is indeed where to find the message(s). So the first two parameters (* and 0) are telling the QMHRMVPM API that the message to be removed can be found in the program message queue of the API caller.

 

The next two parameters, Message key and Messages to remove, also work together and are used to identify the message (or messages) to be removed. In the Automating Recovery article, the respective values ' ' and *ALL instruct the QMHRMVPM API to remove all messages from the call stack entry identified by the Call stack entry and Call stack counter parameters.

 

The fifth parameter, QUSEC, is the standard API error code structure and, due to the setting of the API error code Bytes provided field in the sample program, indicate that any error in removing the message(s) should be returned as an escape message.

 

Returning now to the sample program of More on Message Handling, we could use this same approach for removing the CPF3213 (Members for file more than maximum allowed) message by inserting a call to the QMHRMVPM API within the main procedure as shown below.

 

                        select;                                       

                           when MessageInfo.Common.QMHMI03 = 'CPF3213';

                                HdlCPF3213();

                                RmvMsg('*' :0 :' ' :'*ALL' :QUSEC);   

                           other;                                     

                                SndHardError();                       

                        endsl;                                         

 

This approach will work because the HdlCPF3213 procedure, as coded, will return to the calling procedure only when the recovery logic has successfully run. That is, any failure within HdlCPF3213 will be returned as an escape message and, as the sample program does not have an active monitor for escape messages, the subsequent API call will never run.

 

This approach, however—removing the CPF3213 message within the main procedure—seems awkward to me. To my way of thinking, it would make more sense for the HdlCPF3213 procedure to remove the message when the HdlCPF3213 procedure has resolved the error condition. One possible method for the HdlCPF3213 procedure to remove this diagnostic message is shown here.

 

pHdlCPF3213       b                                                

                                                                  

 /free                                                            

                                                                  

  Cmd = 'CHGPF FILE(SOMEFILE) MAXMBRS(*NOMAX)';                   

  RunCmd(Cmd :%len(%trimr(Cmd)) :QCAP0100 :%size(QCAP0100)        

         :'CPOP0100' :NotUsedChr :0 :NotUsedInt :QUSEC);         

                                                                   

  Cmd = 'ADDPFM FILE(SOMEFILE) MBR(' + PSDS.JobUsr + ')';         

  RunCmd(Cmd :%len(%trimr(Cmd)) :QCAP0100 :%size(QCAP0100)        

         :'CPOP0100' :NotUsedChr :0 :NotUsedInt :ErrCde);         

  if ErrCde.Common.QUSBAVL > 0;                                    

     SndHardError();                                              

  endif;                                                          

                                                                  

  RmvMsg('*' :1 :' ' :'*ALL' :QUSEC);                             

                                 

 /end-free                       

                                 

pHdlCPF3213       e              

 

As you can see above, we have added a call to the QMHRMVPM API to the HdlCPF3213 procedure. When calling the API within the HdlCPF3213 procedure, we have also changed the second parameter, Call stack counter, from the previously used value of 0 to the new value of 1. This change is necessary as the CPF3213 message was not sent to the HdlCPF3213 procedure (or call stack entry). Rather, this message was sent to the caller of HdlCPF3213, where, in the mainline code, we initially attempted to add a member to the file SOMEFILE. The 1 is instructing the QMHRMVPM API to remove all messages from the call stack entry associated with the caller of HdlCPF3213 (rather than HdlCPF3213 itself). If we had left the Call stack counter value at 0, then the QMHRMVPM API would not have removed the CPF3213 message (as it would not have been found). This approach—removing messages from the procedure's caller—while effective at removing the diagnostic message, does however have the potential for some undesirable side effects.

 

The main problem is that HdlCPF3213 is now removing all program messages found in its caller's program message queue or call stack entry. Right now, that isn't a problem as the only message being removed is the CPF3213, but what if six months from now…

 

  • additional processing is added to the main procedure prior to clearing the member of file SOMEFILE?
  • this additional logic includes the logging of message USR5678 to the job log?
  • the message USR5678 is to be retained in the job log when the main program completes successfully?

 

By having the HdlCPF3213 procedure remove all messages from the program message queue of its caller, then whenever HdlCPF3213 successfully recovers from escape message CPF7306 and diagnostic message CPF3213, message USR5678, as an unintended side effect, will also be removed. Note that this removal of all messages in the caller's program message queue can be "just right" for a procedure named RemoveAllMyMessages. It's just that a procedure whose sole function is to recover from message CPF3213 should not, as a side effect, remove all of the caller's program messages. To avoid this problem, and still have the HdlCPF3213 procedure clean up the job log, we need to be more selective in terms of specifying what message is to be removed.

Critical Parameters: Message key and Messages to remove

This is where the Message key and Messages to remove parameters of the QMHRMVPM API come into play. In addition to the special value *ALL for removing all messages, the QMHRMVPM Messages to remove parameter can also be specified with the special value *BYKEY. *BYKEY indicates that the specific message identified by the Message key parameter, and only that message, is to be removed. This message key is a unique key value, assigned by the system, for each message found in the job log of a job. Note the qualifier "in the job log of a job." Duplicate message key values can occur across jobs; it is only within a given job that a message key value is unique. Now the question is "How do I get the message key value for the CPF3213 diagnostic message?" You may recall from last month's article, "More on Message Handling," that when receiving a message with the Receive Program Message (QMHRCVPM) API, format RCVM0100 returns quite a bit of information about the message being received. In particular, the message key is returned in format RCVM0100 at offset 21 or, if you are using the IBM QSYSINC-provided QRPGLESRC include member QMHRCVPM, field QMHMK03. So to have procedure HdlCPF3213 remove the CPF3213 message from the job log, given that we know the correct message key value to specify from our previous use of the QMHRCVPM API, we can call the QMHRMVPM API as shown below.

 

pHdlCPF3213       b                                               

                                                                   

 /free                                                            

                                                                  

  Cmd = 'CHGPF FILE(SOMEFILE) MAXMBRS(*NOMAX)';                    

  RunCmd(Cmd :%len(%trimr(Cmd)) :QCAP0100 :%size(QCAP0100)        

         :'CPOP0100' :NotUsedChr :0 :NotUsedInt :QUSEC);         

                                                                  

  Cmd = 'ADDPFM FILE(SOMEFILE) MBR(' + PSDS.JobUsr + ')';         

  RunCmd(Cmd :%len(%trimr(Cmd)) :QCAP0100 :%size(QCAP0100)        

         :'CPOP0100' :NotUsedChr :0 :NotUsedInt :ErrCde);         

  if ErrCde.Common.QUSBAVL > 0;                                   

     SndHardError();                                               

  endif;                                                          

                                                                  

  RmvMsg('*' :0 :MessageInfo.Common.QMHMK03 :'*BYKEY' :QUSEC);

                                  

 /end-free                       

                                 

pHdlCPF3213       e              

 

When *BYKEY is specified for the Messages to remove parameter of the QMHRMVPM API, the first and second parameters, Call stack entry and Call stack counter, are ignored. As parameters are specified positionally, we have to specify something for these two parameters and have used '*' and 0 for lack of anything better, but these values are not used in locating the message to be removed. The qualified name MessageInfo.Common.QMHMK03 is sufficient for the HdlCPF3213 procedure to uniquely identify the message to be removed.

 

The HdlCPF3213 procedure is now removing the CPF3213 diagnostic message when a member is successfully added to file SOMEFILE. It was noted earlier, though, that two completion messages (CPC7303 and CPC7305) are also in the job log as a result of running the CHGPF and ADDPFM commands during the error recovery logic of HdlCPF3213. These messages were sent to the HdlCPF3213 procedure, so if we want to remove them from the job log, we can simply call the QMHRMVPM API a second time as shown here.

 

pHdlCPF3213       b                                               

                                                                   

 /free                                                            

                                                                  

  Cmd = 'CHGPF FILE(SOMEFILE) MAXMBRS(*NOMAX)';                   

  RunCmd(Cmd :%len(%trimr(Cmd)) :QCAP0100 :%size(QCAP0100)        

         :'CPOP0100' :NotUsedChr :0 :NotUsedInt :QUSEC);         

                                                                  

  Cmd = 'ADDPFM FILE(SOMEFILE) MBR(' + PSDS.JobUsr + ')';         

  RunCmd(Cmd :%len(%trimr(Cmd)) :QCAP0100 :%size(QCAP0100)        

         :'CPOP0100' :NotUsedChr :0 :NotUsedInt :ErrCde);         

  if ErrCde.Common.QUSBAVL > 0;                                   

     SndHardError();                                              

  endif;                                                           

                                                                  

  RmvMsg('*' :0 :MessageInfo.Common.QMHMK03 :'*BYKEY' :QUSEC);

  RmvMsg('*' :0 :' ' :'*ALL' :QUSEC);                   

                                  

 /end-free                       

                                 

pHdlCPF3213       e              

 

With these two API calls, HdlCPF3213 is removing all messages related to the successful handling of CPF7306, leaving the job log with only those messages related to true failures within the application program. This is the approach to removing messages from the job log that I generally recommend and use in my own applications.

Special Value *ALLINACT

Before ending this article, I would like to point out one other special value that the QMHRMVPM API supports—a special value that can be quite helpful but also a bit on the dangerous side. The special value is *ALLINACT for the Call stack entry parameter. *ALLINACT, which requires that you also specify the special value *ALL for the Messages to remove parameter, allows you to remove all messages associated with inactive call stack entries—that is, programs that have returned and not "cleaned up" after themselves. Using this special value, we could for instance have the main procedure of our sample program remove the messages generated by the HdlCPF3213 procedure after the procedure returned (which we might do for example if HdlCPF3213 was provided in a separate module, we didn't have the source code for the module, and we really didn't want the CPC messages in our job log). This special value can be quite useful when calling system functions and/or user applications that leave unwanted messages in the job log.

 

There is, however, an implication with *ALLINACT that catches many by surprise. Let's say you have a program A that calls program B. Program B then calls program C, which generates a few messages in your job log. When program C returns to program B, B can then call the QMHRMVPM API with *ALLINACT and remove all of the messages in program C's program message queue as C is no longer an active call stack entry within your job. Sounds perfect so far, right? Now let's have program A call program X, where X generates a few messages and returns to A. As before, A then calls B, which in turn calls C. When C returns to B, and B uses the *ALLINACT special value of the QMHRMVPM API, the messages associated with both programs X and C will be removed as neither have an active call stack entry. The "surprise" is related to many developers thinking of call stacks in terms of what is directly "above" and "below" them in the call stack. In this case, program X was never "below" (or called) by B, but from a job point of view, X meets all of the requirements of being inactive. When using *ALLINACT, keep in mind that it will remove all messages in the job log that resulted from any commands or programs that have been previously run and that are no longer active in the call stack. Due to this, *ALLINACT may get rid of a lot more messages than you expect.

Unwanted Messages Gone!

In this article, we've looked at several ways that you can remove unwanted messages from your job logs. There are several additional options and features with the QMHRMVPM API that we haven't discussed, but the approaches reviewed here should enable you to more directly control what is, and perhaps more importantly what is not, in your job logs when chasing down a problem.

Questions?

If you have any API questions, send them to me at This email address is being protected from spambots. You need JavaScript enabled to view it.. I'll see what I can do about answering your burning questions in future columns.    

as/400, os/400, iseries, system i, i5/os, ibm i, power systems, 6.1, 7.1, V7,

Bruce Vining

Bruce Vining is president and co-founder of Bruce Vining Services, LLC, a firm providing contract programming and consulting services to the System i community. He began his career in 1979 as an IBM Systems Engineer in St. Louis, Missouri, and then transferred to Rochester, Minnesota, in 1985, where he continues to reside. From 1992 until leaving IBM in 2007, Bruce was a member of the System Design Control Group responsible for OS/400 and i5/OS areas such as System APIs, Globalization, and Software Serviceability. He is also the designer of Control Language for Files (CLF).A frequent speaker and writer, Bruce can be reached at This email address is being protected from spambots. You need JavaScript enabled to view it.. 


MC Press books written by Bruce Vining available now on the MC Press Bookstore.

IBM System i APIs at Work IBM System i APIs at Work
Leverage the power of APIs with this definitive resource.
List Price $89.95

Now On Sale

BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$0.00 Raised:
$

Book Reviews

Resource Center

  • SB Profound WC 5536 Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. You can find Part 1 here. In Part 2 of our free Node.js Webinar Series, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Brian will briefly discuss the different tools available, and demonstrate his preferred setup for Node development on IBM i or any platform. Attend this webinar to learn:

  • SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation. Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects. The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the company are not aligned with the current IT environment.

  • SB HelpSystems ROBOT Generic IBM announced the E1080 servers using the latest Power10 processor in September 2021. The most powerful processor from IBM to date, Power10 is designed to handle the demands of doing business in today’s high-tech atmosphere, including running cloud applications, supporting big data, and managing AI workloads. But what does Power10 mean for your data center? In this recorded webinar, IBMers Dan Sundt and Dylan Boday join IBM Power Champion Tom Huntington for a discussion on why Power10 technology is the right strategic investment if you run IBM i, AIX, or Linux. In this action-packed hour, Tom will share trends from the IBM i and AIX user communities while Dan and Dylan dive into the tech specs for key hardware, including:

  • Magic MarkTRY the one package that solves all your document design and printing challenges on all your platforms. Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product. Make sure your data survives when catastrophe hits. Request your trial now!  Request Now.

  • SB HelpSystems ROBOT GenericForms of ransomware has been around for over 30 years, and with more and more organizations suffering attacks each year, it continues to endure. What has made ransomware such a durable threat and what is the best way to combat it? In order to prevent ransomware, organizations must first understand how it works.

  • SB HelpSystems ROBOT GenericIT security is a top priority for businesses around the world, but most IBM i pros don’t know where to begin—and most cybersecurity experts don’t know IBM i. In this session, Robin Tatam explores the business impact of lax IBM i security, the top vulnerabilities putting IBM i at risk, and the steps you can take to protect your organization. If you’re looking to avoid unexpected downtime or corrupted data, you don’t want to miss this session.

  • SB HelpSystems ROBOT GenericCan you trust all of your users all of the time? A typical end user receives 16 malicious emails each month, but only 17 percent of these phishing campaigns are reported to IT. Once an attack is underway, most organizations won’t discover the breach until six months later. A staggering amount of damage can occur in that time. Despite these risks, 93 percent of organizations are leaving their IBM i systems vulnerable to cybercrime. In this on-demand webinar, IBM i security experts Robin Tatam and Sandi Moore will reveal:

  • FORTRA Disaster protection is vital to every business. Yet, it often consists of patched together procedures that are prone to error. From automatic backups to data encryption to media management, Robot automates the routine (yet often complex) tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:

  • FORTRAManaging messages on your IBM i can be more than a full-time job if you have to do it manually. Messages need a response and resources must be monitored—often over multiple systems and across platforms. How can you be sure you won’t miss important system events? Automate your message center with the Robot Message Management Solution. Key features include:

  • FORTRAThe thought of printing, distributing, and storing iSeries reports manually may reduce you to tears. Paper and labor costs associated with report generation can spiral out of control. Mountains of paper threaten to swamp your files. Robot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing. Manage your reports with the Robot Report Management Solution. Key features include:

  • FORTRAFor over 30 years, Robot has been a leader in systems management for IBM i. With batch job creation and scheduling at its core, the Robot Job Scheduling Solution reduces the opportunity for human error and helps you maintain service levels, automating even the biggest, most complex runbooks. Manage your job schedule with the Robot Job Scheduling Solution. Key features include:

  • LANSA Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.

  • LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed. Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

  • LANSASupply Chain is becoming increasingly complex and unpredictable. From raw materials for manufacturing to food supply chains, the journey from source to production to delivery to consumers is marred with inefficiencies, manual processes, shortages, recalls, counterfeits, and scandals. In this webinar, we discuss how:

  • The MC Resource Centers bring you the widest selection of white papers, trial software, and on-demand webcasts for you to choose from. >> Review the list of White Papers, Trial Software or On-Demand Webcast at the MC Press Resource Center. >> Add the items to yru Cart and complet he checkout process and submit

  • Profound Logic Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application.

  • SB Profound WC 5536Join us for this hour-long webcast that will explore:

  • Fortra IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn: