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:
- Placement: The
ON-EXIT
section is placed at the end of the subprocedure, after all other code. - Execution: This section runs when the subprocedure ends, regardless of how it ends (normal completion, return statement, unhandled exception, or cancellation).
- 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-pi mainline;
end-pi;
// subprocedure main code here
something = something + somethingelse
// handle abnormal end
else;
callp close(myfiles);
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:
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:
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…