CPF9999 is a defined message in QCPFMSG message file that is sent by the operating system whenever a message is not being monitored in a program and an error occurs. Normally it is preceded by an error message that defines in detail what actually happened.
CPF0000, however, is not an actual message per se. It is used in a MONMSG command to monitor for all message that start with CPF. It can be placed after the last DCL to do a global monitor throughout the CL porgram or immediately after a command to monitor on that command only.
Likewise you can do a MONMSG RPG0000 to monitor for messages starting with RPG.
Although it is easy to code a MONMSG CPF0000, most people recommend looking at the help text for a command to see what error message might be sent from the command and specifically monitoring for them.
Hope this helps.
Monitoring for CPF0000 will catch every message starting with “CPF” that is sent within the scope of the monitor. (“Every message” means every *EXCEPT, *STATUS or *NOTIFY message. “Scope” can be global to the procedure or local to the preceding command.)
That implies that a CPF9999 message will be caught by monitoring for CPF0000.
By using zeros at the end of the message identifier, you create a ‘generic’ monitor. (See <a href=”http://publib.boulder.ibm.com/infocenter/iseries/v5r4/topic/rbam6/monmg.htm”>Monitoring for messages in a CL program or procedure</a> for details.)
CPF0000 is the ultimate generic identifier for “CPF” messages.
Note that monitoring for CPF0000 will not catch “MCH” messages nor messages beginning with “RNX”, “SQL” nor any other prefix. However…
An unmonitored *ESCAPE message (with any prefix) will eventually generate an event called a “function check”. This results in CPF9999 being sent — which <i>would</i> be caught by CPF0000. (For a flowchart of the basic sequence, see <a href=”http://publib.boulder.ibm.com/infocenter/iseries/v5r4/topic/rbam6/dfthd.htm”>CL handling for unmonitored messages</a>.)
An *ESCAPE message might have everything needed to diagnose the problem or it might be preceded by one or more *DIAG messages. When CPF9999 is sent, the preceding messages provide diagnostic info that are necessary for determining what happened.
The CPF9999 message data can identify the CL source statement where the original problem arose. The statement number is part of the message, helping to identify the cause.
The original *ESCAPE message isn’t lost. The CPF9999 just replaces it as the most recent one. Full error-handling code needs to be more robust if it’s going to be complete.
In short, both message identifiers will catch all messages. CPF0000 is generally easier and more direct; CPF9999 might be more useful for developers, perhaps during testing.