How to capture AS400 system error message and use it as my own program message in CL?

11,813

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)
Share:
11,813
God_of_Thunder
Author by

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, 2022

Comments

  • God_of_Thunder
    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
    God_of_Thunder over 11 years
    In 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
    Buck Calabro over 11 years
    This 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
    God_of_Thunder over 11 years
    Why monitor CPF0000 and MCH0000 after SNDPGMMSG? Expect it to fail somehow?
  • Buck Calabro
    Buck Calabro over 11 years
    If 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
    God_of_Thunder over 11 years
    Is 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
    God_of_Thunder over 11 years
    Why 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
    Buck Calabro over 11 years
    Go 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
    God_of_Thunder over 11 years
    I 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
    Buck Calabro over 11 years
    When 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
    God_of_Thunder over 11 years
    Just 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
    Buck Calabro over 11 years
    CHGMSGQ, 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
    God_of_Thunder over 11 years
    When 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
    Buck Calabro over 11 years
    Do 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
    God_of_Thunder over 11 years
    I did what you said in a command line, and it said *DSPMSG on top right. What else could be different? System configuration?
  • Buck Calabro
    Buck Calabro over 11 years
    I'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
    God_of_Thunder over 11 years
    Just found that in QCMD the message type is Escape, but under PDM it is information. Why?
  • Buck Calabro
    Buck Calabro over 11 years
    Because 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.