• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • APIs Sometimes Fail (But Programmers Don’t Have To)

    October 3, 2007 Ted Holt

    My ambition is to eventually be as smart as my teenagers. Some days I think I’ll make it. After all, my old man became downright brilliant once I left home and had to start paying my own bills. On other days, like days when I try to write computer programs, I have the gravest of doubts.

    One of those days occurred recently, when I spent half a day trying to find a bug in my code. It turned out that a call to the Send Program Message API, QMHSNDPM, was failing, and I wasn’t bothering to check whether the call succeeded or not. My friend Cletus the Codeslinger reveled in ragging me about it. “What moron told you you were fit to be a programmer?” he sneered. “If you’d read my assertions article, that wouldn’t have happened.” Of course, I did read the article–I’m the editor. But it’s foolish to argue with someone when he’s right.

    Most System i APIs, including QMHSNDPM, use a data structure to report errors. (Exceptions are the ILE CEE APIs, which use feedback codes and conditions, and the Unix-type, and National Language Data Conversion, which use the errno variable.) The data structure has two formats–ERRC0100 and ERRC0200. You can use either one. Or you can tell the API to send an escape message, rather than load a data structure.

    Let’s look at an RPG prototype for the API that got me in trouble.

    D SendPgmMsg      pr                  extpgm('QMHSNDPM')
    D   MsgID                        7    const
    D   MsgFile                     20    const
    D   MsgDta                      80    const
    D   MsgDtaLen                   10i 0 const
    D   MsgType                     10    const
    D   MsgQ                        10    const
    D   MsgQNbr                     10i 0 const
    D   MsgKey                       4
    D   Error                      ????
    

    The ninth parameter, which I have defined with question marks for now, tells QMHSNDPM how the programmer wants the API to report errors. The first four bytes of the error parameter contain a binary number, which is the key to the whole thing. If that number is zero, the API is to report errors by sending diagnostic and escape messages. If that number is positive, the API is to report errors through a data structure formatted according to the ERRC0100 format. If that number is negative one, the API is to report errors through the data structure according to the ERRC0200 format.

    If you want to receive diagnostic and escape messages, you don’t even need a data structure. A scalar value will do. Notice the last line of the prototype, where the error parameter is defined as a four-byte integer.

    D SendPgmMsg      pr                  extpgm('QMHSNDPM')
    D   MsgID                        7    const
    D   MsgFile                     20    const
    D   MsgDta                      80    const
    D   MsgDtaLen                   10i 0 const
    D   MsgType                     10    const
    D   MsgQ                        10    const
    D   MsgQNbr                     10i 0 const
    D   MsgKey                       4
    D   Error                       10i 0 const
    

    Here’s a call to the API that illustrates this option.

     /free
         monitor;
            SendPgmMsg ('CPF9898': 'QCPFMSG   QSYS':
                MsgDta: %len(MsgDta): '*INFO': '*PGMBDY': 1:
                MsgKey: *zero);
            on-error;
                // it bombed; do something
            endmon;
    

    If you prefer to use the data structure, that’s fine. I have found ERRC0100 to be sufficient. You can pass it as many bytes as you wish. I recommend a minimum of 16 bytes, but I have come to prefer 272, as this length allows for 256 bytes of message data.

    Here’s the revised prototype and the data structure for the error feedback.

         D SendPgmMsg      pr                  extpgm('QMHSNDPM')
         D   MsgID                        7    const
         D   MsgFile                     20    const
         D   MsgDta                      80    const
         D   MsgDtaLen                   10i 0 const
         D   MsgType                     10    const
         D   MsgQ                        10    const
         D   MsgQNbr                     10i 0 const
         D   MsgKey                       4
         D   Error                             like(ErrorDS)
    
         D ErrorDS         ds           272    qualified
         D   BytesProv                   10i 0 inz(%size(ErrorDS))
         D   BytesAvail                  10i 0
         D   ExceptionID                  7
         D                                1
         D   ExceptionDta               256
    

    Here’s the call.

    SendPgmMsg ('CPF9898': 'QCPFMSG   QSYS':
       MsgDta: %len(MsgDta): '*INFO': '*PGMBDY': 1:
       MsgKey: ErrorDS);
    if ErrorDS.BytesAvail > *zero;
       // it bombed; do something
    endif;
    

    If the call succeeds, you will find a zero in the bytes-available subfield. If the call fails, you will receive a positive value in the bytes-available subfield, a seven-byte message ID in ErrorDS.ExceptionID, and the message data for the error in ErrorDS.ExceptionDta. Do not test the call by checking those last two subfields for non-blanks. After a successful call, they may continue to contain data from an earlier, failed call.

    You must use ERRC0200 if you want convertible character support. I’ve never used ERRC0200, so I threw together an example. You may come up with something better.

    Here’s the prototype again, with the revised error data structure and a separate scalar variable for exception data.

    D SendPgmMsg      pr                  extpgm('QMHSNDPM')
    D   MsgID                        7    const
    D   MsgFile                     20    const
    D   MsgDta                      80    const
    D   MsgDtaLen                   10i 0 const
    D   MsgType                     10    const
    D   MsgQ                        10    const
    D   MsgQNbr                     10i 0 const
    D   MsgKey                       4
    D   Error                             like(ErrorDS)
    
    D ErrorDS         ds          1024    qualified
    D   Key                         10i 0 inz(-1)
    D   BytesProv                   10i 0 inz(%size(ErrorDS))
    D   BytesAvail                  10i 0
    D   ExceptionID                  7
    D                                1
    D   CCSID                       10i 0
    D   ExcDtaOffset                10i 0
    D   ExcDtaLength                10i 0
    
    D ExceptionDta    s            256
    

    The stand-alone exception data variable is necessary because the location of exception data is not fixed within the data structure. You have to look at the offset and length subfields in order to find the exception data. The following code loads the exception data if the call fails.

    clear ExceptionDta;
    SendPgmMsg ('CPF9898': 'QCPFMSG   QSYS':             
        MsgDta: %len(MsgDta): '*INFO': '*PGMBDY': 1:     
        MsgKey: ErrorDS);                                
    if ErrorDS.BytesAvail > *zero;                      
       // it bombed                                     
       // retrieve the exception data                   
       if ErrorDS.ExcDtaLength <= %size(ExceptionDta);  
          ExceptionDta = %subst(ErrorDS:                
                             ErrorDS.ExcDtaOffset + 1:  
                             ErrorDS.ExcDtaLength);     
       else;                                            
          ExceptionDta = %subst(ErrorDS:                
                             ErrorDS.ExcDtaOffset + 1:  
                             %size(ExceptionDta));      
       // do whatever else                              
       endif;                                           
    endif;
    

    I learned a lesson from my experience: Checking for API execution errors is easy. The hard part might be remembering to do so.



                         Post this story to del.icio.us
                   Post this story to Digg
        Post this story to Slashdot

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags:

    Sponsored by
    WorksRight Software

    Do you need area code information?
    Do you need ZIP Code information?
    Do you need ZIP+4 information?
    Do you need city name information?
    Do you need county information?
    Do you need a nearest dealer locator system?

    We can HELP! We have affordable AS/400 software and data to do all of the above. Whether you need a simple city name retrieval system or a sophisticated CASS postal coding system, we have it for you!

    The ZIP/CITY system is based on 5-digit ZIP Codes. You can retrieve city names, state names, county names, area codes, time zones, latitude, longitude, and more just by knowing the ZIP Code. We supply information on all the latest area code changes. A nearest dealer locator function is also included. ZIP/CITY includes software, data, monthly updates, and unlimited support. The cost is $495 per year.

    PER/ZIP4 is a sophisticated CASS certified postal coding system for assigning ZIP Codes, ZIP+4, carrier route, and delivery point codes. PER/ZIP4 also provides county names and FIPS codes. PER/ZIP4 can be used interactively, in batch, and with callable programs. PER/ZIP4 includes software, data, monthly updates, and unlimited support. The cost is $3,900 for the first year, and $1,950 for renewal.

    Just call us and we’ll arrange for 30 days FREE use of either ZIP/CITY or PER/ZIP4.

    WorksRight Software, Inc.
    Phone: 601-856-8337
    Fax: 601-856-9432
    Email: software@worksright.com
    Website: www.worksright.com

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Sponsored Links

    COMMON:  Join us at the annual 2008 conference, March 30 - April 3, in Nashville, Tennessee
    Help/Systems:  Discover Robot/SECURITY, the i5/OS security monitoring and auditing software
    NowWhatJobs.net:  NowWhatJobs.net is the resource for job transitions after age 40

    IT Jungle Store Top Book Picks

    The System i RPG & RPG IV Tutorial and Lab Exercises: List Price, $59.95
    The System i Pocket RPG & RPG IV Guide: List Price, $69.95
    The iSeries Pocket Database Guide: List Price, $59.00
    The iSeries Pocket Developers' Guide: List Price, $59.00
    The iSeries Pocket SQL Guide: List Price, $59.00
    The iSeries Pocket Query Guide: List Price, $49.00
    The iSeries Pocket WebFacing Primer: List Price, $39.00
    Migrating to WebSphere Express for iSeries: List Price, $49.00
    iSeries Express Web Implementer's Guide: List Price, $59.00
    Getting Started with WebSphere Development Studio for iSeries: List Price, $79.95
    Getting Started With WebSphere Development Studio Client for iSeries: List Price, $89.00
    Getting Started with WebSphere Express for iSeries: List Price, $49.00
    WebFacing Application Design and Development Guide: List Price, $55.00
    Can the AS/400 Survive IBM?: List Price, $49.00
    The All-Everything Machine: List Price, $29.95
    Chip Wars: List Price, $29.95

    Laserfiche Scales to Meet Content Management Needs of i5/OS Shop IBM Preps Update to Virtualization Manager

    Leave a Reply Cancel reply

Volume 7, Number 34 -- October 3, 2007
THIS ISSUE SPONSORED BY:

WorksRight Software
Vision Solutions
ARCAD Software

Table of Contents

  • IFS Commands Give You Generic Access
  • APIs Sometimes Fail (But Programmers Don’t Have To)
  • Admin Alert: Remotely Accessing an HMC System Console, Part 1

Content archive

  • The Four Hundred
  • Four Hundred Stuff
  • Four Hundred Guru

Recent Posts

  • Public Preview For Watson Code Assistant for i Available Soon
  • COMMON Youth Movement Continues at POWERUp 2025
  • IBM Preserves Memory Investments Across Power10 And Power11
  • Eradani Uses AI For New EDI And API Service
  • Picking Apart IBM’s $150 Billion In US Manufacturing And R&D
  • FAX/400 And CICS For i Are Dead. What Will IBM Kill Next?
  • Fresche Overhauls X-Analysis With Web UI, AI Smarts
  • Is It Time To Add The Rust Programming Language To IBM i?
  • Is IBM Going To Raise Prices On Power10 Expert Care?
  • IBM i PTF Guide, Volume 27, Number 20

Subscribe

To get news from IT Jungle sent to your inbox every week, subscribe to our newsletter.

Pages

  • About Us
  • Contact
  • Contributors
  • Four Hundred Monitor
  • IBM i PTF Guide
  • Media Kit
  • Subscribe

Search

Copyright © 2025 IT Jungle