How to capture AS400 system error message and use it as my own program message in CL?
This is my standard CL error handling process. Generally, I would use MONMSG inline to handle errors I expect might be coming. Also generally, for errors I expect, I do not normally tell the end user about them. If you need to do that, make the RCVMSG/SNDPGMMSG pairs into a subroutine and call that inline to percolate the errors to the caller. The idea is to receive the diagnostic messages and re-send them to the caller, then do the same with the exception message.
PGM
DCL &MSGID *CHAR 7
DCL &MSGDTA *CHAR 256
/* Trap all errors, and let the error routine handle */
MONMSG (CPF0000 MCH0000) EXEC(GOTO ERROR)
/* processing happens here */
/* if an unexpected error occurs, we drop to the error routine */
/* We expect this error, but tell the caller about it anyway */
dltf mylib/myfile
monmsg cpf2105 exec(do)
callsubr percolate
endoo
/* end of processing */
RETURN
/* This is the error handling routine. Basically it */
/* simply re-sends the messages back up to the */
/* caller, so it dies "gracefully" instead of */
/* giving a hard halt. */
/* Re-send diagnostic messages */
ERROR: RCVMSG MSGTYPE(*DIAG) MSGDTA(&MSGDTA) MSGID(&MSGID)
IF (&MSGID *EQ ' ') GOTO ERROR_ESC
SNDPGMMSG MSGID(&MSGID) MSGF(QCPFMSG) MSGDTA(&MSGDTA) +
MSGTYPE(*DIAG)
MONMSG (CPF0000 MCH0000)
GOTO ERROR
/* Re-send escape message and RETURN */
ERROR_ESC: RCVMSG MSGTYPE(*EXCP) MSGDTA(&MSGDTA) MSGID(&MSGID)
SNDPGMMSG MSGID(&MSGID) MSGF(QCPFMSG) MSGDTA(&MSGDTA) +
MSGTYPE(*ESCAPE)
MONMSG (CPF0000 MCH0000)
RETURN
ENDPGM
EDIT: Add subfile message queue to answer.
Perhaps a subfile message queue? DDS:
A R BMENUS SFL
A*
A TEXT('Message subfile')
A SFLMSGRCD(20)
A WMSGK SFLMSGKEY
A WPGMQ SFLPGMQ
A R BMENUC SFLCTL(BMENUS)
A*
A TEXT('Message subfile control recor-
A d')
A OVERLAY
A LOCK
A SFLDSP
A SFLINZ
A SFLSIZ(0006)
A SFLPAG(0003)
A WPGMQ SFLPGMQ
CLP:
DCLF FILE(BMENUFM)
...
CHGVAR &WPGMQ 'BMENU'
...
SNDF RCDFMT(BMENUC)
SNDRCVF RCDFMT(BMENUR)
God_of_Thunder
Currently working as an IT contractor on IBM AS/400 platform. Interesting in all sorts of different programming methods and techniques.
Updated on June 04, 2022Comments
-
God_of_Thunder almost 2 years
I am writing a CL program which is going to encounter a lot of errors, due to the fact that it will be executed in environments with all sorts of problems like missing objects (yes, that is deliberate). Instead of monitoring these possible messages and bypass the errors, I actually would like to redirect these messages so that they can be used the program messages and displayed to the user. So what I want is that after the program execution, the program puts all the error messages onto display on the bottom of the screen rather than having them pop up and disrupt the execution. Is it possible to do so? How?
-
God_of_Thunder over 11 yearsIn this way the program itself is not going to complete what it has been designed for, right? Suppose there is a second DLTF after ENDDO, this statement is not going to be executed, is it?
-
Buck Calabro over 11 yearsThis is an example of how I currently do it. You don't have to copy it exactly - feel free to make the processing from ERROR: on down into a subroutine... in my example code I called it PERCOLATE. Look up CALLSUBR It works at V5R4 on up.
-
God_of_Thunder over 11 yearsWhy monitor CPF0000 and MCH0000 after SNDPGMMSG? Expect it to fail somehow?
-
Buck Calabro over 11 yearsIf there is a problem and it fails inside the error handler, the global MONMSG will loop the code back into the standard error handler. Which would fail and loop, etc.
-
God_of_Thunder over 11 yearsIs it possible to just somehow redirect the message queue setting so that all error messages in this program will automatically goto the program message queue?
-
God_of_Thunder over 11 yearsWhy did you use message type *diag here? I tried your example today and it seems that CPF2105 is type *info when I displayed the message details.
-
Buck Calabro over 11 yearsGo to a command line. Type DLTF GGGGGG. Press Enter. The CPF2105 you get is a *ESCAPE message. Now try this: MOVOBJ OBJ(QGPL) OBJTYPE(*lib) TOLIB(QSYS). The command fails with a CPF0001 *ESCAPE message, but it has a CPD0084 *DIAG message explaining why. In my standard error handling, the *DIAG messages are helpful, so I percolate them up the call stack.
-
God_of_Thunder over 11 yearsI have tried to delete a file in command line. The I moved the cursor to the message and pressed F1 to display the additional information, then F9 to display the details. The message type shown is information.
-
Buck Calabro over 11 yearsWhen I do the same thing, CPF2105 is an Escape message. Are you using a break message handling program? Do a DLTF and do not press Enter - press F4 then F1 then F2. Scroll to the very bottom - there you will see a list of escape messages the DLTF command can send.
-
God_of_Thunder over 11 yearsJust did what you said and CPF was indeed listed as one of the escape messages so this is a bit confusing now. What is a break message handling program?
-
Buck Calabro over 11 yearsCHGMSGQ, F4 to prompt. F9 for additional parameters. See the Break Handling Program parameter? It allows you to assign a program to handle the messages instead of displaying them on the screen.
-
God_of_Thunder over 11 yearsWhen I did the DLTF in command line the message was displayed on the bottom of the screen. Do you think that break message handling program has been involved here?
-
Buck Calabro over 11 yearsDo DSPMSG. Look at the upper right. If the 'Program' says *DSPMSG, then there's no break message handler. Are you at a command line, or in a menu? To get to the command line, CALL QCMD.
-
God_of_Thunder over 11 yearsI did what you said in a command line, and it said *DSPMSG on top right. What else could be different? System configuration?
-
Buck Calabro over 11 yearsI'm not sure why you would be seeing Informational messages. It sounds to me as though you are in a program/menu. DSPJOB and see what is in the call stack. My call stack is QCMD, then my initial program, then QCMD. What I am sure of is that CPF2105 is an Escape message, and your CL program would need to monitor for that. Have you tried changing your CL program or have you only been working on the command line?
-
God_of_Thunder over 11 yearsJust found that in QCMD the message type is Escape, but under PDM it is information. Why?
-
Buck Calabro over 11 yearsBecause PDM is a program. As a program, it is doing what I suggest you do: monitor, receive and re-send Escape and Diagnostic messages. PDM resends them as Informational messages specifically so that the error does not get pushed up to the caller. Resending as an Escape will force the caller to deal with the error. There is a good explanation of messages in the Infocenter.