惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
Check Point Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 聂微东
月光博客
月光博客
博客园 - 司徒正美
爱范儿
爱范儿
aimingoo的专栏
aimingoo的专栏
量子位
Recent Announcements
Recent Announcements
V
V2EX
P
Proofpoint News Feed
小众软件
小众软件
云风的 BLOG
云风的 BLOG
腾讯CDC
宝玉的分享
宝玉的分享
Microsoft Azure Blog
Microsoft Azure Blog
大猫的无限游戏
大猫的无限游戏
Vercel News
Vercel News
The GitHub Blog
The GitHub Blog
A
About on SuperTechFans
B
Blog
博客园_首页
GbyAI
GbyAI
博客园 - Franky

Comments for IT Jungle

Guru: Where’s The Table? - IT Jungle Will Power Chips Get A Converged Arm Instruction Set Like Z Mainframe CPUs? - IT Jungle Oracle Dips A Toe Into IBM’s EBCDIC World - IT Jungle Inside The Security Enhancements In ACS - IT Jungle Guru: Assertions, Take 2 - IT Jungle Guru: Claude’s SQL Tip - IT Jungle Guru: Beyond Three-Part Naming – Running SQL Across Remote IBM i Systems - IT Jungle Does AI Mark The End Of The ERP Era? - IT Jungle Guru: Deterministic Application Development With AI - IT Jungle What IBM’s Got Cooking In Db2 For i In The Summer TRs - IT Jungle Guru: Creating Excel Spreadsheets With Python - IT Jungle The Power11 IBM i P05 Entry Machine Finally Arrives - IT Jungle Guru: Analyzing User Session Statistics, Part 1 - IT Jungle Your IBM i Jobs Don’t Live On An Island Anymore - IT Jungle Present Timestamps in the Local Time Zone - IT Jungle Set Your Library List From A Job Description - IT Jungle GenAI Is The Death Of Deterministic Project Budgeting - IT Jungle Guru: Single Threading A Program Execution - IT Jungle Guru: Where’s The Table? - IT Jungle Big Blue Unveils Bob Premium Pack For IBM i - IT Jungle Guru: SQL Sequences In RPG Let Db2 Handle The Counting - IT Jungle DB2 for i 7.2 Features and Fun, Part 1 - IT Jungle Guru: DateTime Rules Of Thumb - IT Jungle Spring IBM i Tech Refreshes Will Come A Bit Later This Year - IT Jungle As I See It: The Surgical Years - IT Jungle After A Few Short Years, VS Code Passes Rational Developer for i - IT Jungle Guru: Managing The Lifecycle Of Your Service Programs – Updates Without Chaos - IT Jungle Where We Are And Where We Are Headed With AI On IBM i - IT Jungle And Then There Were Two: Big Blue Withdraws IBM i 7.4 - IT Jungle Guru: When Attention Turns To You – Writing Your Own ATTN Program - IT Jungle
Guru: Putting Failure Handling In Its Place - IT Jungle
Gregory Simmons · 2026-08-24 · via Comments for IT Jungle

August 24, 2026

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