10
Sun, Nov
10 New Articles

An Error by Any Other Name

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

Errors are an unfortunate fact of life for programmers. When they occur, they are usually followed immediately by screaming and hollering (some directed at programmers, some produced by programmers). Knowing how to deal with them may reduce the stress level of all parties concerned.

Quick! All programmers who have never had a “bug” occur in a program they have written, raise your hand! For those of you liars out there who actually raised your hands, do you know how silly you look to anyone who happens to be passing your cubicle right now?

Obviously, bugs are both an unfortunate and inevitable byproduct of programming in any language, but this reality does not mean that the users of your programs have to encounter them. There are preventative steps you can take to be prepared for them.

What Is a Bug?

If we left this definition up to our illustrious president, we would all be in trouble. Anyone who is unable to define the word is would surely be lost when it came to finding a definition for the term bug as it relates to programming.

The term bug actually originated back in the days of the dinosaur computers (the ones used when we were young). You know the ones we are referring to—those behemoth-sized computers with huge vacuum tubes instead of microchips. When insects would get caught in the machinery, they would cause the switches to malfunction. The outcome of this particular situation resulted in a definition of the term bug that even Bill Clinton could understand. The term bug has since evolved to equate with any unintended computer function.

Some might argue that, since computers can do only what they are told to do, there is no such thing as a bug. These are generally the same people who raised their hands while reading the first paragraph of this article. They reason, “If your program doesn’t account for an error, the operating system takes over and does what it is programmed to do; therefore, there are technically no ‘unintended’ computer functions.” Use this argument at your own peril because users can sometimes be hostile. This is especially true if the user

happens to be staring at some unfamiliar error screen while running a month-end in the middle of the night. Humor is generally not a viable option at these unplanned and unappreciated moments.

But the key point in the preceding statement is that your program may be designed to account for almost all conceivable errors. When you write a new program, you decide what course of action is to be taken when an error occurs. The user (or customer, in our case) should not be the one to decide what to do in the middle of a highly stressful situation. The best time to account for errors is before they occur (too bad President Clinton didn’t think about that!).

The Basics

Errors in RPG programs are generally divided into two classifications: file and program. Likewise, there are generally two simple ways of handling errors in RPG programs. For the former type, you can use error indicators on all file access operation codes, and, for the latter, you can code an error subroutine. Let’s examine each of these methods in some detail.

Using error indicators on file access operation codes is your way of telling the operating system not to take control when some problem develops while trying to access a file. Instead of turning control over to the operating system, the error indicator is turned on so that your program can handle exceptions. For those of you who dislike indicators, RPG IV now allows the use of an extender (E) for a lot of operation codes in place of an error

indicator. The extender enables the built-in-function (BIF) %ERROR to return a value of 1 (on) if an error has occurred or 0 (off) if the operation finished successfully. Using the extender and the %ERROR function together allows you to code without using an indicator.

Program Subroutines

A good method of handling program errors is to use a *PSSR subroutine in your program. Figure 1 shows an example of a program with a *PSSR subroutine. It also shows our preferred method of calling that subroutine when an error occurs (as opposed to allowing the system to call the subroutine automatically). The program shown displays the name of the job that has a lock on the record it is trying to access. Indicator 99 comes on after the maximum record wait time has expired, indicating that an error has occurred within the file. If indicator 99 is turned on, we then execute the *PSSR subroutine. We don’t have to code a call to the *PSSR subroutine. If we code an INFSR(*PSSR) keyword in the File Specification and leave the error indicator off of the Chain statement, the system will recognize that a *PSSR subroutine exists to handle the error and will automatically execute the routine.

So why do we bother coding the Invoke Subroutine (EXSR) statement for our *PSSR subroutine? The reason has to do with what happens after the subroutine executes. If we execute the subroutine by coding a call to it, control can return to the next statement following the EXSR statement. If we let the system call the subroutine, then we have less control over the return point. We tell the system where to return after executing the subroutine by entering a keyword in factor two of the End of Subroutine (ENDSR) statement. Figure 2 shows the valid keywords and their corresponding return points. You should note that all of these return points are areas within the RPG cycle, except the value of blanks. If we use blanks (or don’t code a return point) and we use EXSR to call the subroutine, control returns to the next line of code.

Let’s take a look inside the *PSSR subroutine itself. Because the subroutine is called anytime an unexpected error occurs in the program, what happens if an error occurs from within the subroutine? The subroutine is called again, which causes the error to occur again, which calls the subroutine again, which...well, you get the picture.

To prevent this occurrence, we use a field named InSub to tell us that we have been inside the subroutine. The possible values for InSub are either *ON or *OFF. If InSub is

File It!

on, then the error we are handling must have come from inside the *PSSR subroutine, since that is the only place where we set the value of InSub to *ON. In this case, we set the return point to *CANCL and let the RPG default exception handler issue its nasty error message. If InSub is not on, we set it on and check the field STATUS to determine the exact nature of the error that has occurred. In this example, if it’s a “Record in Use” error, we use the DSPLY operation code to display the name of the job that has the record locked.

File Subroutines

Another type of error-handling subroutine that you should be aware of and code into your programs is the File Error Subroutine. This subroutine takes control when an error occurs during an explicit file operation that does not have an error indicator specified, such as Chain or Read.

To indicate that you want a file error subroutine to execute automatically when an error occurs while trying to access data in a file, specify the Information Subroutine (INFSR) keyword. The parameter for this keyword is the name of the subroutine to be executed. You can see an example of this in Figure 3.

The INFSR tells the system the name of the subroutine you have written to handle errors for that file. In the example in Figure 3, the subroutine is named FILESR. The INFDS code is used to indicate the name of a data structure (INFO) that the system will load with information about the file. One of the key pieces of information about the file is the STATUS field, which contains an error code indicating the exact problem with the file.

In the example shown in Figure 3, the program attempts to read the file FAMLY before opening it. The keyword USROPN on the file definition keeps the system from opening it automatically; therefore, the program should “blow up” on the first read of the file. However, there is a file information subroutine (FILESR) defined for the file, so the system passes control to it. This subroutine checks the status code, and if the message is I/O to a closed file, it opens the file and returns control to the system at the beginning of the detail calculations. We really should include a disclaimer here about opening your files. This example is meant to show you how to code programs that prevent errors from reaching the end user. Opening your files by using an exception error is obviously not the best way to code your programs.

If you want, you can code a different subroutine for each file, or you can have each file call the same subroutine. You can even have the file information subroutine be the *PSSR subroutine. It’s a flexible system and one that is simple to exploit.

You should be aware that if the problem with the file occurs during the implicit opening of the files, your subroutine does not get control. The default exception handler (the system) takes control, no matter what. This is one good example of why you should employ user-controlled file opens rather than let the system do it for you.

Make It So, Number One

Yet another error handling technique that we like is the system reply list. We love this technique because you tell the system what to do before the error occurs, and the system takes that action when the error occurs. The system actually enters your response to an error message for you without interrupting the job!

The system reply list is a list of error messages. Figure 4 shows a couple of entries on the list. To see your list, use the Work with Reply List Entries (WRKRPYLE) command. To add a new entry to the list, use the F6 key. You can see the result of this operation in Figure 5. Let’s examine the parameters of this command in detail.

• The sequence number is assigned by you and is used to order the messages. The system searches the list in sequence number order.

• The message identifier is the ID of the message to which you want the system to respond automatically.

• The Compare data parameter allows you to get very specific about when the system will answer the message. The string you enter here is compared to the message data specified for the inquiry message. The second part of this parameter allows you to specify

where in the message data the comparison should start. If your string and the data match, the system answers the message. If they don’t, the system continues the search with the next entry in the list.

• The Message reply parameter is used to specify the answer that the system is to give to the message it issues.

Now that you have the list created, you need to tell the system that you want the job to use the list. For an interactive job, you can use the Change Job (CHGJOB) command to change the Inquiry message reply (INQMSGRPY) parameter from *RQD (response is required) to *SYSRPYL (use the system reply list). One other option for this parameter is *DFT (use the default reply for the message).

For submitted jobs, the same INQMSGRPY parameter exists on the Submit Job (SBMJOB) command, with one possible variation: You can specify *JOBD, which means, “Go get the value for this parameter from the job description” (which has the exact same INQMSGRPY parameter).

If All Else Fails, Call ‘Em Something Else

We have given you a few of our favorite tips that you can use to prevent the programs in your system from terrorizing your users.

Remember, errors need not be feared if you handle them properly. If all else fails, you can put some presidential spin on them and call them “features” instead.

FFamly uf e k disk infds(info)
dInfo ds
dStatus *STATUS
d sds
d MsgDta 91 170

dFldReturn s 6
dInSub s 1
dKey s 9 0
dmsgHld s 52

* Attempt to get record (if locked by another job, *in99 will

* come on after the default record wait parameter expires)
c eval Key = 1
c eval Insub = *off
c Key chain Famly 6899
c if *in99 = *on
c exsr *pssr
c endif
c eval *inlr = *on

* Error handling routine
c *PSSR begsr
c If InSub = *on
c eval FldReturn = '*CANCL'
c else
c eval InSub = *on
c eval FldReturn = *blanks
c if Status = 01218
c movel MsgDta MsgHld
c msghld dsply
c endif
c endif
c endsr Fldreturn

Figure 1: Using a *PSSR subroutine is good way to handle errors.

Keyword Return Point *DETL Beginning of detail lines *GETIN Get input record routine *TOTC Beginning of total calculations *TOTL Beginning of total lines
*OFL Beginning of overflow lines *DETC Beginning of detail calculations *CANCL Cancel the processing of the program Blanks Next sequential instruction after the EXSR statement.

If no EXSR statement, return to ILE RPG default exception handler

Figure 2: Control return points via these keywords.

FFamly if e k disk infds(info) infsr(FILESR) usropn
dInfo ds
dStatus *STATUS
dFldReturn s 6
dInSub s 1

c read Famly 9968
c eval *inlr = *on

* file error handling
c FileSr begsr
c If InSub = *on
c eval FldReturn = '*CANCL'
c else
c eval InSub = *on
c eval FldReturn = *blanks
c if Status = 01211
c open famly
c eval fldreturn = '*DETC'
c endif
c endif
c endsr Fldreturn

Figure 3: This is a file Information Subroutine (INFSR) example.

Work with System Reply List Entries

System: CPU35

Type options, press Enter.

2=Change 4=Delete

Sequence Message Compare

Opt Number ID Reply Compare Value Start

_ 8888 RPG8888 C *NONE

_ 9999 CPF4058 I *NONE

Bottom

Figure 4: The system reply list offers another method to handle errors.

Add Reply List Entry (ADDRPYLE)

Type choices, press Enter.

Sequence number . . . . . . . . 1-9999

Message identifier . . . . . . . *ANY Character value, *ANY

Compare data:

Comparison data . . . . . . . *NONE

Message data start position . *NONE 1-999, *NONE

Message reply . . . . . . . . . *DFT

Bottom

F3=Exit F4=Prompt F5=Refresh F10=Additional parameters F12=Cancel

F13=How to use this display F24=More keys

Figure 5: Use the Add Reply List Entry display to add entries to the system reply list.

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: