• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • Guru: Putting Failure Handling In Its Place

    August 24, 2026 Gregory Simmons

    One of the things I enjoy most about procedure-driven RPG is that it encourages us to think about responsibility. Every procedure should have a clear purpose. It should perform one task well and leave unrelated concerns to other parts of the application.

    That sounds straightforward enough, yet one responsibility often finds its way into nearly every procedure we write: failure handling.

    If you have worked with RPG for any length of time, you have probably encountered applications where nearly every procedure begins with a MONITOR operation. The procedure performs its work, catches any exception that occurs, logs an error, returns an indicator or status code, and continues.

    There is nothing inherently wrong with that approach. The MONITOR operation is one of RPG’s most useful language features, and there are many situations where it is exactly the right tool for the job.

    The question isn’t whether a procedure can handle its own failures. The question is whether it is the best place to decide what should happen when something goes wrong.

    Consider the following procedure:

     
    dcl-proc Customer_Save export; 
    
    monitor; 
      // Save the customer record 
      SaveCustomerRecord(customer); 
      return *on;   
    on-error; 
      Error_Log(); 
      return *off; 
    endmon; 
    
    end-proc; 
    
    

    At first glance, the procedure appears perfectly reasonable. It saves a customer and reports whether the operation succeeded.

    Looking a little closer, however, reveals that it is actually performing three different responsibilities. It saves a customer, decides how exceptions should be handled, and decides how those exceptions should be logged. While those responsibilities often appear together, they are not necessarily related.

    Suppose your organization decides that every application error should be written to a database table instead of a spool file. Or perhaps operations want every failure forwarded to an enterprise monitoring solution. If every service procedure contains its own logging logic, those changes could affect hundreds of source members.

    And let’s be honest, how likely is your department to approve a project whose sole purpose is modifying 500 or 600 programs just to change how failures are logged?

    Yes, AI-assisted development tools can help reduce the amount of manual effort required to make those changes. They can help locate code, generate modifications, and accelerate development. But they do not eliminate the need to test those changes, coordinate deployments, or manage the impact of modifying hundreds of objects.

    Good architecture still matters because it reduces the number of objects that need to change in the first place.

    The problem isn’t the MONITOR operation. The problem is that responsibility for failure handling has become scattered throughout the application.

    One question I often ask while designing a procedure is this: “If this procedure disappeared tomorrow, what capability would the application lose?”

    If Customer_Save() disappeared, the application should lose its ability to save customers. It shouldn’t also lose its ability to log failures. Those are separate capabilities, and they deserve separate homes within the application.

    This leads to another important distinction: not every failure is an exception.

    Suppose a customer number cannot be found. Depending on the application, that may not represent an error at all. It may simply mean the user entered an invalid customer number. Likewise, a validation routine may reject an order because a required field is missing. Those are business outcomes. The caller should expect them and decide how to respond.

    Unexpected failures belong in a different category. A called procedure sends an escape message. An array index falls outside its valid range. A decimal data error occurs. These situations represent conditions that the application did not anticipate during normal processing.

    Embedded SQL provides another example. A failed SQL statement does not normally trigger an RPG MONITOR block. Instead, SQL reports the condition through SQLSTATE, SQLCODE, and diagnostic information. Those conditions still need to be considered, but they represent a different type of failure from an RPG exception.

    Treating every failure as though it were an exception often leads to procedures filled with MONITOR blocks, logging code, and status indicators, making the business logic progressively more difficult to follow.

    A common mistake is treating every unsuccessful operation as something exceptional. Sometimes the operation completed exactly as designed; it simply produced a result that the caller needs to consider.

    Consider an order creation process. A customer may have passed validation, but their credit limit may not allow the order to proceed. Inventory may not be available. A required approval may still be pending.

    None of those situations represent a programming failure. They are expected outcomes of the business process.

    Instead of forcing those situations through exception handling, the procedure can communicate the result directly.

     
    
    dcl-ds OrderResult qualified; 
      Success ind; 
      CreditHold ind; 
      InventoryUnavailable ind; 
      ApprovalRequired ind; 
    end-ds; 
    
    OrderResult = Order_Create(order); 
    
    select; 
    when OrderResult.Success; 
      SendConfirmation(); 
    when OrderResult.CreditHold; 
      NotifyCreditDepartment(); 
    when OrderResult.InventoryUnavailable; 
      CreateBackorder(); 
    when OrderResult.ApprovalRequired; 
      RouteForApproval(); 
    other; 
      Error_Log();
    endsl;
    
    

    The procedure creating the order does not need to know what the application should do with each outcome. Its responsibility is to determine the result and communicate it clearly.

    The workflow, on the other hand, understands the larger business process and can decide how to respond.

    Now consider the same application flow when we separate business outcomes from unexpected failures.

    monitor; 
      Customer_Validate(customer); 
      Customer_Save(customer); 
      Customer_EmailWelcome(customer); 
    on-error; 
      Error_Log(); 
    endmon; 
    
    

    The service procedures now concentrate entirely on the work they were written to perform. Validation validates. Saving saves. Sending the welcome email sends the welcome email. The workflow coordinates those operations and determines what should happen if one of them cannot complete successfully.

    This approach also creates a natural place for centralized logging. Rather than every procedure deciding what information should be recorded, an error service can consistently gather the call stack, message information, job details, timestamps, and any other diagnostics your organization requires.

    If those requirements change in the future, the modification is made in one place instead of throughout the application.

    None of this suggests that MONITOR belongs only in the highest-level procedure. There are certainly situations where a lower-level procedure understands an exception well enough to recover from it and continue processing. In those cases, handling the exception locally is often the right design.

    The important question is whether the procedure truly owns that decision. If it can recover because it understands the operation it is performing, handling the exception locally makes sense. If it cannot, allowing the caller to determine how to proceed usually produces code that is easier to understand and easier to maintain.

    Like many aspects of software design, there is no rule that fits every situation. The goal isn’t to eliminate MONITOR. The goal is to place responsibility where it belongs.

    A procedure that retrieves a customer should retrieve customers. A procedure that calculates shipping charges should calculate shipping charges. A service responsible for logging failures should log failures.

    Good architecture isn’t measured by how many procedures an application contains or how many service programs have been created. It is measured by how little of the application has to change when the requirements do.

    Failures are a normal part of software. The goal is not to pretend they will never happen. The goal is to ensure that each failure is communicated to the part of the application that has enough context to make the right decision.

    When every component focuses on its primary responsibility, the application becomes easier to understand, easier to test, and easier to evolve.

    Until next time, happy coding.

    Gregory Simmons is a Project Manager with PC Richard & Son. He started on the IBM i platform in 1994, graduated with a degree in Computer Information Systems in 1997 and has been working on the OS/400 and IBM i platform ever since. He has been a registered instructor with the IBM Academic Initiative since 2007, an IBM Champion and holds a COMMON Application Developer certification. When he’s not trying to figure out how to speed up legacy programs, he enjoys speaking at technical conferences, running, backpacking, hunting, and fishing.

    RELATED STORIES

    Guru: Beyond Three-Part Naming – Running SQL Across Remote IBM i Systems

    Guru: Finding Data In The Forest – Exploring Three-Part Naming In SQL

    Guru: SQL Sequences In RPG Let Db2 Handle The Counting

    Guru: IBM i Job Log Detective Brings Structure To Job Log Analysis In VS Code

    Guru: Managing The Lifecycle Of Your Service Programs – Updates Without Chaos

    Guru: Are Binding Directories A Shortcut Or A Source Of Chaos?

    Guru: Service Programs And Activation Groups – Design Decisions That Matter

    Guru: Binder Source Is Your Service Program’s Owner’s Manual

    Guru: Access Client Solutions 1.1.9.11 – Security First, With Continued Investment In SQL Tooling

    Guru: Taming The CRTSRVPGM Command – Options That Can Save Your Sanity

    Guru: CRTSRVPGM Parameters That Can Save or Sink You

    Guru: A First Look at Bob, The IBM i Assistant That’s Closer Than You Think

    Bob More Than Just A Code Assistant, IBM i Chief Architect Will Says

    IBM Pulls The Curtain Back A Smidge On Project Bob

    Big Blue Converges IBM i RPG And System Z COBOL Code Assistants Into “Project Bob”

    Guru: When Attention Turns To You – Writing Your Own ATTN Program

    Guru: WCA4i And Granite – Because You’ve Got Bigger Things To Build

    Guru: When Procedure Driven RPG Really Works

    Guru: Unlocking The Power Of %CONCAT And %CONCATARR In RPG

    Guru: AI Pair Programming In RPG With Continue

    Guru: AI Pair Programming In RPG With GitHub Copilot

    Guru: RPG Receives Enumerator Operator

    Guru: RPG Select Operation Gets Some Sweet Upgrades

    Guru: Growing A More Productive Team With Procedure Driven RPG

    Guru: With Procedure Driven RPG, Be Precise With Options(*Exact)

    Guru: Testing URLs With HTTP_GET_VERBOSE

    Guru: Fooling Around With SQL And RPG

    Guru: Procedure Driven RPG And Adopting The Pillars Of Object-Oriented Programming

    Guru: Getting Started With The Code 4 i Extension Within VS Code

    Guru: Procedure Driven RPG Means Keeping Your Variables Local

    Guru: Procedure Driven RPG With Linear-Main Programs

    Guru: Speeding Up RPG By Reducing I/O Operations, Part 2

    Guru: Speeding Up RPG By Reducing I/O Operations, Part 1

    Guru: Watch Out For This Pitfall When Working With Integer Columns

    Share this:

    • Share on Reddit (Opens in new window) Reddit
    • Share on Facebook (Opens in new window) Facebook
    • Share on LinkedIn (Opens in new window) LinkedIn
    • Share on X (Opens in new window) X
    • Email a link to a friend (Opens in new window) Email

    Tags: Tags: 400guru, FHG, Four Hundred Guru, IBM i, RPG, SQL

    Sponsored by
    New Generation Software, Inc.

    It’s Time!
    Replace IBM Query/400 and DB2 Web Query with NGS-IQ.

    IBM retired Query/400 and DB2 Web Query long ago. Is your company still at the party?
    Don’t keep your users waiting.

    Watch a demo on demand and see how NGS-IQ can save you time creating and updating ad-hoc queries; production reports; Excel sheets, tables, and ranges; Adobe PDF files; Web reports; and multidimensional models.

    www.ngsi.com – 800-824-1220

    Share this:

    • Share on Reddit (Opens in new window) Reddit
    • Share on Facebook (Opens in new window) Facebook
    • Share on LinkedIn (Opens in new window) LinkedIn
    • Share on X (Opens in new window) X
    • Email a link to a friend (Opens in new window) Email

    Inside The Security Enhancements In ACS When Your Small IBM i Team Is Really A Team Of One

    One thought on “Guru: Putting Failure Handling In Its Place”

    • ema tissani says:
      August 24, 2026 at 8:41 am

      a good design can be observed in the system API… if you pass a datastructure the error is set there otherwise it can raise an exception… so basically the caller can decide if a full blown stack exceptions is needed or not.. very flexible

      Reply

    Leave a ReplyCancel reply

TFH Volume: 36 Issue: 29

This Issue Sponsored By

  • FalconStor
  • Maxava
  • New Generation Software, Inc.
  • JAMS Software
  • WorksRight Software
  • Raz-Lee Security

Table of Contents

  • Oracle Dips A Toe Into IBM’s EBCDIC World
  • When Your Small IBM i Team Is Really A Team Of One
  • Guru: Putting Failure Handling In Its Place
  • Inside The Security Enhancements In ACS
  • IBM i PTF Guide, Volume 28, Number 28: A Crazy Number of Security Vulnerability Patches
  • IBM i PTF Guide, Volume 28, Number 29

Content archive

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

Recent Posts

  • Will Power Chips Get A Converged Arm Instruction Set Like Z Mainframe CPUs?
  • Thinking About Moving IBM i To The Cloud? Don’t Start With The Quote
  • Precisely To Add Ransomware Protection In MIMIX 11
  • It’s D-Day For Cybersecurity, AI Firms Warn
  • IBM i PTF Guide, Volume 28, Number 30
  • Oracle Dips A Toe Into IBM’s EBCDIC World
  • When Your Small IBM i Team Is Really A Team Of One
  • Guru: Putting Failure Handling In Its Place
  • Inside The Security Enhancements In ACS
  • IBM i PTF Guide, Volume 28, Number 28: A Crazy Number of Security Vulnerability Patches

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