I am sure all IBM i (AS400) programmers are familiar with the MONMSG command in CL to capture exceptions (errors) and stop an error message from interrupting the program. You can do the same in your RPG code using what IBM calls the "monitor group".
The "monitor group" consists of the MONITOR, ON-ERROR, and ENDMON operation codes. When an error occurs within the "monitor group" it can be handled by using specific status codes, or by the use of one of the following special values *PROGRAM, *FILE, *ALL. *PROGRAM handles all of the program related status codes, 100 - 999. *FILE handles all of the file related errors, 1000 - 9999. *ALL, as it suggests, handles all errors, and is the default for the the ON-ERROR operation.
The basic layout of a "monitor group" is as follows:
01 monitor ; 02 03 on-error <status-code or special-value> ; 04 05 on-error <another-status-code or special-value>; 06 07 on-error ; 08 09 endmon ;
The "monitor group" starts with the MONITOR operation code, line 1.
The statements that appear between the MONITOR and the first ON-ERROR is what is being monitored. This could be more than one line of code.
The ON-ERROR on line 3 could be for a specific status code or one of the special values mentioned above. If that condition is true line 4 would be executed. Status codes are numeric fields, therefore, code 00100 can be typed as 100.
In this example if the first ON-ERROR was not true the next one, line 5, is tested.
The last ON-ERROR is what I call the "catch all", i.e. if it is an error that is not handled by one of the above ON-ERROR this one catches it. Think of it like the OTHER operation in a select group or the final ELSE in an IF-ELSEIF group.
At the end of the "monitor group" is the ENDMON operation code.
Warning: If an operation code uses the 'E' operation extender the error is handled by that rather than the "monitor group".
Rather than list all of the status codes in this post I am going to refer you to the page on IBM's website for IBM i 7.1.
Below are some examples. The first is how I could capture a "divide by zero" error, program status code 00102:
01 monitor ; 02 eval(h) Result = Nbr1 / Nbr2 ; 03 on-error 102 ; 04 Result = 0 ; 05 Error = 'Divide by 0' ; 06 endmon ;
What is wrong with the example below?
01 monitor ; 02 open(e) FILE ; 03 on-error *file ; 04 Error = 'File not opened' ; 06 endmon ;
As the OPEN operation code has the 'E' operation extender the "monitor group" does not monitor the message. If the operation extender is removed then the "monitor group" is executed, see below:
01 monitor ; 02 open FILE ; 03 on-error *file ; 04 Error = 'File not opened' ; 06 endmon ;
The example below shows that there can be multiple status codes on the same ON-ERROR, lines 5 and 7:
01 monitor ; 02 in *lock DataArea ; 03 DataArea += 1 ; 04 out DataArea ; 05 on-error 401 : 411 ; 06 Error = 'Data Area not found' ; 07 on-error 412 : 413 ; 08 Error = 'Data Area update error' ; 09 endmon ;
You can learn more about these operatin codes on the IBM web site:
This article was written for IBM i 7.1, and it should work with earlier releases too.