One of the strengths of CL is its ability to handle error situations gracefully. In this respect, it cannot be surpassed.
Every time the system finds a problem with a command you run, it sends an *ESCAPE message. A complete explanation of i5/OS messaging is not provided in this book of basics. Messages are of different types, and one of those types is *ESCAPE. Escape messages are only issued when an error occurs that is serious enough to merit canceling the command you requested to run.
For example, you type the following command at the command line:
DSPLIB LIB(XYZ) OUTPUT(*PRINT)
When the system receives this request, it checks to see that library XYZ exists. If it does, the DSPLIB command runs without trouble. If it doesn't, the system sends an *ESCAPE message.
Because you are running the DSPLIB command from the keyboard, you see the message and think, "Oh, I must have made a mistake." Then you try again. Perhaps the name of the library was not XYZ but XXX.
CL programs are not so fortunate. If the DSPLIB command shown above were part of a CL program, and you execute the program, the DSPLIB command would fail just as quickly and issue the same *ESCAPE message. This *ESCAPE message would force your CL program to abort.
You can use the MONMSG command to trap *ESCAPE messages and take care of the problem gracefully. To use this command, do the following:
Find out what message ID the system issues for the error condition you want to be ready for. For example, the Delete File (DLTF) command issues message CPF2105 (the message ID) if the file doesn't exist.
Code a MONMSG command immediately after the statement you think will issue the *ESCAPE message. For example, you would code a MONMSG command after the DLTF command if you think that the file will not exist when the DLTF command is executed.
Here is an example of what the sequence looks like:
DLTF FILE(MYLIB/MYFILE) MONMSG MSGID(CPF2105) EXEC(...)
The MONMSG command shown above has two parameters: MSGID, which lists the message IDs you want to watch out for (you can include several) and the EXEC parameter, which should contain a command you want to run if CPF2105 is issued.
You can omit the EXEC parameter if you don't want to do anything, such as if you want to ignore the *ESCAPE message. Alternatively, you can also put a DO command in the EXEC parameter if you want to execute several commands. In this case, the sequence of commands will have to be terminated with an ENDDO command:
DLTF FILE(MYLIB/MYFILE) MONMSG MSGID(CPF2105) EXEC(DO) : : ENDDO
The MONMSG command can also be placed at the top of the CL program, immediately after the DCL/DCLF commands. If placed there, MONMSG acts as a blanket that covers the entire program. Every statement in the CL program is "protected" by the MONMSG command. This arrangement is usually called a global or programlevel MONMSG.
The global MONMSG can include only a GOTO command in its EXEC parameter, or it can have the EXEC parameter omitted. Usually, the global MONMSG is used for catch-all situations. In this case, it is common practice to monitor for CPF0000.
CPF0000 is a wild card. It is the same as saying "monitor for any CPFXXXX error message." The CL program will be protected from any CPFXXXX error message. Another blanket message ID is any message ID ending in two zeros, such as CPF1400, which covers any message between CPF1401 and CPF14FF.