RPG ON-EXIT is housekeeping for sub-procedures

RPG ON-EXIT is a nice structured way of storing procedure house keeping and/or error catching.

The ON-EXIT opcode in RPG is used to define a section of code that runs whenever a subprocedure ends, whether it ends normally or abnormally. This is particularly useful for cleanup tasks, such as deallocating resources or handling errors.

So how does ON-EXIT work?

Here’s a brief overview of how it works:

  1. Placement: The ON-EXIT section is placed at the end of the subprocedure, after all other code.
  2. Execution: This section runs when the subprocedure ends, regardless of how it ends (normal completion, return statement, unhandled exception, or cancellation).
  3. Indicator: You can specify an indicator to determine if the subprocedure ended abnormally. If the subprocedure ends normally, the indicator is set to *OFF; if it ends abnormally, the indicator is set to *ON.

Example

dcl-proc myprocedure;
  dcl-pi mainline;
  end-pi; 

  dcl-s abnormal_end ind inz(*on);

  // subprocedure main code here
  something = something + somethingelse
  
  on-exit abnormal_end;

    if abnormal_end;
      // handle abnormal end
    else;
      // common end of subprocedure things:
      callp close(myfiles);
   endif;

end-proc;

In this example, the ON-EXIT section ensures that the cleanup code runs regardless of how the subprocedure ends.

The ON-EXIT operation code begins the ON-EXIT section. The ON-EXIT section contains code that runs every time that the procedure ends, whether it ends normally or abnormally. The ON-EXIT section runs under the following conditions:

  • The procedure reaches the end of the main part of the procedure.
  • The procedure reaches a RETURN operation.
  • The procedure ends with an unhandled exception.
  • The procedure is canceled, due to the end of the job or subsystem, or due to an exception message being sent to a procedure higher in the call stack.

By placing your clean-up code, such as deleting temporary files and deallocating heap storage, in the ON-EXIT section, you ensure that it is always run, even if your procedure ends with an unhandled exception, or if it is canceled.

Extended Factor 2 contains an optional indicator variable that indicates whether the procedure ended normally or abnormally. If the procedure returned normally, the indicator is set to *OFF. If the procedure ended with an unhandled exception or if the procedure was canceled for any other reason, the indicator is set to *ON.

The ON-EXIT section is coded at the end of the subprocedure, following any subroutines.

All variables and files defined in the procedure are available in the ON-EXIT section.


So, how about using ON-EXIT something like this:

**free
dcl-proc myproc;
dcl-pi *n ind;
incomingParameter int(10);
end-pi;

dcl-s success ind inz(*off);
dcl-s monitorCommandFailed ind inz(*off);

Open fileName;

// do lots of subprocedure logic stuff
// this is where you might have lots of RPG logic

if something;
  calculate = some + things;
endif;
doStuff = things * widgets / shoeshize;
filename = crtTempFile();
incomingParameter += 1;

// we could also handle errors this way
monitor;
  doSomethingThatFailsAlot(incomingParameter);
on-error;
  monitorCommandFailed = *on;
  return;
endif;

success = *on;

return;

on-exit monitorCommandFailed;

// then we could have some logic added around the "myProcFinished" indicator
if success;
  close fileName;
  dltTempFile (filename);
endif;

// "monitorCommandFailed" is set *ON if the on-exit is invoked abnormally
// (so it acts sort of like a *PSSR capture)
if monitorCommandFailed;
  reportProblem ();
endif;

// any housekeeping that we want to do if we finished cleanly or not
Close fileName;

end-proc;

That’s only rough code but it should give you the idea…

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}
>