08
Fri, Nov
10 New Articles

Simplify Interactive Error Handling with ILE RPG and APIs

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

As long as human beings are entering data into computers, there are going to be data entry errors. Data entry errors are as inevitable as death and taxes (our apologies to Ben Franklin). A good computer system can diagnose some of these errors and not others. But one thing is certain: How interactive data entry programs are written can have a big impact on the quality of the data in the system. The better the error messages presented in the case of error are, the more likely it is that the resultant data entered into the system will be correct.

This article deals with using APIs and ILE procedures to create informative and useful error messages in your interactive RPG programs. We will also explore how to use a technique called wrapping to remove some of the complexities of using APIs in your RPG programs. Let’s get down to the nitty-gritty.

Begin at the Beginning

Error message subfiles have been with RPG almost since the beginning of interactive midrange programming (or at least as long as we can remember, which is pretty much the same thing). The concept of presenting an error with the message subfile is rather simple. The user fills in multiple data entry fields on a screen and presses Enter. In turn, the program validates all of the entries and writes an error message to the program’s message queue for each of the errors it finds. The program then redisplays the screen along with a message subfile of all errors found in the message queue. The operator may page through the resulting error messages, correct the data, and press Enter again. The process repeats itself until the program deems the data valid, at which point the appropriate data is written to a database file.

This all sounds simple enough, but, as you know, the devil is in the details. One of the best ways to make your data entry programs more intuitive is to deliver quality error messages to the operator. For example, “Invalid customer number” is not nearly as precise as “Customer number 12345 is invalid.” Obviously, error messages containing the erroneous data are much more helpful. One of the ways to employ this technique is to use the Send Program Message (QMHSNDPM) API.

You can use the Send Program Message API to send a message to the message queue along with related message data. But the challenge with this technique is that the Send Program Message API includes 10 parameters, nine of which are required. This makes using the API a lot of work. We are going to show you a way to avoid all of that. Figure 1 shows an example of a program using our Send Error Message (SndErrMsg) and Remove Error Message (RmvErrMsg) ILE procedures. As you can see from the code, this type of error handling logic is not difficult. The sample code in Figure 1 displays a screen asking for input. In the next step, the RmvErrMsg procedure is called to remove any previously sent messages from the program message queue. Since our RmvErrMsg procedure does not return any values, our sample code uses the CALLP op code to execute it. The user then edits the data on the screen, and the SndErrMsg procedure executes for each error found. We coded our message subfile using the SFLINZ (Initialize Subfile) keyword so that multiple error messages will be displayed in the subfile when the message control record is displayed. The operator may then “page” through the error messages using the Page Up and Page Down keys, as with any standard subfile.

Signed, Sealed, and Delivered

We’ll take a closer look at how the SndErrMsg procedure is used in Figure 1. As with any ILE procedure, we’ll start with the procedure interface. The first keyword you see is Operational Descriptor (OPDESC). This keyword tells the system that information about the parameters will be accessible to the procedure via the Retrieve Operational Descriptor API. We’ll talk more about this option further on.

Notice that every parameter has the CONST (Constant) keyword. This tells you that the procedure that is called will not change any of those parameters. It also tells you that the calling program can pass the parameters with literals as well as fields.

Now, let’s look at the PMSGDATA parameter. This parameter has two keywords, *VARSIZE and *NOPASS. The *NOPASS value indicates that this parameter does not have to be passed to this procedure. The *VARSIZE keyword indicates that the length of the field being passed for this parameter can be variable in size, or, in other words, of any length. With both keywords in place, message data does not have to be passed with the error message, but, if the data is passed, it can be of any length.

Three parameters of our procedure remain: type of error message, error file name, and error file library. All of these parameters contain the *NOPASS keyword and are therefore not required parameters. The variables DefMsgFile and DefMsgLib contain the default error message file name and default library name that the program uses if you do not pass in these parameters. For our purposes, we’ve set the defaults to the qualified message file name CPUMSGF/C50LIB. You probably do not have this library or message file on your system. Therefore, you must change these fields to default to your own message file, or you must always pass these parameters when you call the procedure. The field DefMsgType contains the default message type.

Procedurally Speaking...

Figure 2 shows the SndErrMsg procedure. Now, let’s take a look at what this procedure actually does. If you have passed message data to this procedure (%PARMS are greater than 1), the procedure must determine the length of that data. To figure out the length of the data, we call the Retrieve Operational Descriptor API, CEEDOD.

The first parameter for the CEEDOD API is a number that corresponds to the parameter order that was passed to our procedure. We have coded a numeral 2 because we are trying to gather information about the second parameter passed to this procedure, which happens to be our message data. The next four parameters return some basic information about the type of data being passed. Because we are not interested in the type of data, only the length, we can ignore these parameters. The sixth parameter, INLEN, gives us the

length of the data being passed. The last parameter is an optional feedback code indicating errors. We have omitted this parameter.

Once we have used the CEEDOD API to determine the length of our message data, we can call the Send Program Message API. This API will actually send the error message to the message queue of the calling program. If you look closely at the parameters for this API, you will see that the first five parameters correspond roughly to the procedure interface for the SndErrMsg procedure. The message data length that we have retrieved is the fourth parameter for the API. The message file and library are one of the API parameters. We simply pass on the information to this API using either our established default values or the values passed to this procedure as parameters. The user does not need to know about the last four parameters—message queue, message queue number, message key, and error data structure. We’ve supplied the values for those parameters that make the SndErrMsg procedure work.

The reason we went through all of this is that we are able to hide some of the complexity of the API from the programmer using the procedure. This technique is called wrapping. (No, this does not refer to gift wrap, and we certainly are not going to break into rhyme.) We use this process to simplify working with the API.

You Don’t Know What You’ve Got till It’s Gone

Last but not least is getting rid of messages in the program message queue. One of the difficulties that can occur when presenting subfile error messages is making the last error message go away. For instance, say a program presents a screen, the user edits the entries, and he or she receives an error message. The user corrects the error and presses the Enter key, but he or she makes another error in a different field. The program edits the fields and wants to display a new error. But when the program displays the subfile, it contains both the old and the new errors! In order to eliminate this problem, you need to remove the messages from the message queue after you have displayed them.

You can use the Remove Program Messages (QMHRMVPM) API to eliminate those old errors in the message queue. We have wrapped a procedure around the Remove Program Messages API, too, and named it RmvErrMsg. Figure 3 shows this code. All you have to do is call the procedure after displaying your input screen.

The RmvErrMsg procedure accepts one optional parameter, and that is the message ID that you want to remove. The default value for this is *ALL, which removes all messages from the program message queue. Some of the other values that you could pass are the following:

• *KEEPRQS—clear all messages except request messages

• *NEW—clear messages that have not been received

• *OLD—clear only messages that have been received

The Remove Program Messages API accepts other values for this parameter (such as *BYKEY) that work in conjunction with a message key parameter. If you enter any of these other values or any invalid value, the procedure will not remove messages. In order to keep the code in this procedure to a minimum, we did not design the program to edit any of the values in this field. It’s up to you to put in only valid values or modify the procedure to edit the values.

Putting It All Together!

Compiling the procedures in Figure 2 and Figure 3 is simple. You should create the procedures using the Create RPG Module (CRTRPGMOD) command shown at the top of

each source listing. You should then bind the modules into a service program using the Create Service Program (CRTSRVPGM) command: We recommend that you store the prototype statements in source members and bring them into the program using the /COPY function. In order to minimize the number of figures for this article, we have not done that here. As with any program using a procedure, you cannot compile it using the default activation group, so your Create Bound RPG Program (CRTBNDRPG) statement might look something like this:

CRTBNDRPG PGM(SOMEPGM) DFTACTGRP(*NO) ACTGRP(QILE)

If you’d like, you can see an example of these procedures in action. The editors of Midrange Computing have developed a sample program that uses SndErrMsg and RmvErrMsg. You can download it at www.midrangecomputing.com/mc. If you need more details regarding procedures, prototypes, and ILE concepts, refer to our article “Wanna Play Center Field?” in the February 2000 issue of MC.

ILE can be complex and confusing, but it does not have to be. We are big believers in the KISS (Keep It Simple, Stupid!) method, and you should be, too. While the procedures can be somewhat complex, using them is a snap!

References and Related Materials

“Wanna Play Center Field?” Doug Pence and Ron Hawkins, MC, February 2000

* This is sample code intended only to demonstrate how to use

* SndErrMsg and RmvErrMsg procedures.

*

FDisplayFilcf e workstn
FCustomer if e k disk

* Prototype for send error message (should actually be a /COPY)
d SndErrMsg PR opdesc
d PMsgId 10 const
d PMsgData 32766 const options(*varsize:*nopass)
d PMsgInType 10 const options(*nopass)
d PMsgFile 10 const options(*nopass)
d PMsgLib 10 const options(*nopass)

* Prototype for remove error message (should actually be a /COPY)
d RmvErrMsg PR
d PRmvId 10 const options(*nopass)

c Dou *in61 = *off

* Display the messages in the subfile
c WRITE MSGCTL

* Display a screen for the user to enter information. User enters

* a customer number that is not on file in the Customer file
c exfmt format4

* Remove any previously displayed messages from the joblog
c callp RmvErrMsg

* If customer does not exist, issue error message and pass customer

* number to display in error message
c @CustNbr Chain Customer 61
c if *in61
c callp SndErrMsg(‘USR0453’:@CustNbr)
c endif
c enddo

CRTSRVPGM SRVPGM(XXXLIB/SOMENAME)MODULE(XXXLIB/
SNDERRMSG XXXLIB/RMVERRMSG)

KISS!

Figure 1: This program fragment shows how to use the SndErrMsg and RmvErrMsg ILE procedures.

HNOMAIN

*

* CRTRPGMOD MODULE(XXXLIB/SNDERRMSG) SRCFILE(XXXLIB/QRPGLESRC)

*

* procedure name: SndErrMsg

*

* procedure function: Send a program message wrapper 4 QMHSNDPM API.

* SndErrMsg prototype

d SndErrMsg PR opdesc

d PMsgId 10 const

d PMsgData 32766 const options(*varsize:*nopass)

d PMsgInType 10 const options(*nopass)

d PMsgFile 10 const options(*nopass)

d PMsgLib 10 const options(*nopass)

P SndErrMsg B export

d SndErrMsg PI opdesc
d MsgInId 10 const
d MsgInData 32766 const options(*varsize:*nopass)
d MsgInType 10 const options(*nopass)
d MsgFile 10 const options(*nopass)
d MsgLib 10 const options(*nopass)

d DefMsgFile s 10 inz(‘CPUMSGF ‘)
d DefMsgLib s 10 inz(‘C50LIB ‘)
d DefMsgType s 10 inz(‘*DIAG ‘)
d MsgFileLib s 20
d MsgData s like(MsgInData)
d MsgDtaLen s 6 0
d MsgId s 10
d MsgKey s 9b 0
d MsgQueue s 10
d MsgQueNbr s 9b 0
d MsgType s 10

D ErrorDs DS INZ
D BytesProv 1 4B 0 inz(116)
D BytesAval 5 8B 0
D MessageId 9 15
D Err### 16 16
D MessageDta 17 116 *-----------------------------------------------------------------*

* Prototype for CEEDOD (Retrieve operational descriptor)

*-----------------------------------------------------------------*

D CEEDOD PR
D ParmNum 10I 0 CONST
D 10I 0
D 10I 0
D 10I 0
D 10I 0
D 10I 0
D 12A OPTIONS(*OMIT)

* Parameters passed to CEEDOD
D DescType S 10I 0
D DataType S 10I 0
D DescInfo1 S 10I 0
D DescInfo2 S 10I 0
D InLen S 10I 0
D HexLen S 10I 0 *

c move MsgInId MsgId

c if %parms > 1
c callp CEEDOD(2 :DescType:DataType:
c DescInfo1 : DescInfo2: Inlen:
c *OMIT)
c move Inlen MsgDtaLen
c move MsgInData MsgData
c else
c clear MsgDtaLen
c clear MsgData
c endif

c if %parms >= 3
c eval MsgType = MsgIntype
c else
c eval MsgType = DefMsgType
c endif

c if %parms >= 4
c movel MsgFile MsgFileLib
c else
c movel DefMsgFile MsgFileLib
c endif

c if %parms >= 5
c move MsgLib MsgFileLib
c else
c move DefMsgLib MsgFileLib
c endif

C CALL ‘QMHSNDPM’
C PARM MsgId
C PARM MsgFileLib
C PARM MsgData
C PARM MsgDtaLen
C PARM MsgType
C PARM ‘*’ MsgQueue
C PARM 1 MsgQueNbr
C PARM MsgKey
C PARM ErrorDs

c return
P SndErrMsg E

*************** Beginning of data *************************************

HNOMAIN

*

* CRTRPGMOD MODULE(XXXLIB/RMVERRMSG) SRCFILE(XXXLIB/QRPGLESRC)

*

* procedure name: RmvErrMsg

*

* procedure function: Remove program messages wrapper 4 QMHRMVPM API.

* Usually used to clear previously displayed

* error messages.

* RmvErrMsg prototype

d RmvErrMsg PR

d PRmvId 10 const options(*nopass)

P RmvErrMsg B export

d RmvErrMsg PI

d RmvId 10 const options(*nopass)

d DefRmvMsg s 10 inz(‘*ALL ‘)
d CallStack s 10 inz(‘* ‘)
d CallStackC s 9b 0 inz(1)
d RmvKey s 4
d RmvMsg s 10

D ErrorDs DS INZ
D BytesProv 1 4B 0 inz(116)
D BytesAval 5 8B 0
D MessageId 9 15
D Err### 16 16
D MessageDta 17 116

*

c if %parms = 1

c move RmvId RmvMsg

c else

c move DefRmvMsg RmvMsg

c endif

C CALL ‘QMHRMVPM’

C PARM CallStack

C PARM CallStackC

C PARM RmvKey

C PARM RmvMsg

C PARM ErrorDs

c return
P RmvErrMsg E

Figure 2: The SndErrMsg procedure makes it easy for you to display helpful error messages to users.

Figure 3: The RmvErrMsg procedure deletes error messages after the user has seen them.

BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$

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: