Program Dump on Active Job

Use this board for starting discussions, asking questions, and giving advice on RPG programming for the IBM i platform (and predecessors.)
devinst
Profound User
Posts: 80
Joined: Mon Apr 20, 2009 11:26 am
First Name: Devin
Last Name: St. Germain
Company Name: Dupre Logistics, LLC
Phone: 337.314.2259
Address 1: 201 Energy Pkwy. Ste. 500
City: Lafayette
State / Province: Louisiana
Zip / Postal Code: 70508
Country: United States
Contact:

Program Dump on Active Job

Post by devinst »

Per the advice from Scott K. I started inserting a monitor statement at the beginning of my web programs that will catch an error in the main sub routine and end the job normally. (example below) When the error does occur a routine is executed that will produce a PDF document of the job log and email it to myself. This is working great..!! (Thanks Scott)
However, I was wondering if there is a way to do the same with a program dump of field values? For instance, I see that the last thing the program did was to attempt to write a record with a duplicate key. I would like to know what the value of the key fields were at that time. That would also be helpful with other errors.
I am using a DSPJOBLOG OUTPUT(*PRINT) to retrieve the job log but am unable to find a like command for a program dump. Any suggestions?

//
// *********************************************************************
// Main Processing
// *********************************************************************
//
// Execute Main Procedure
//
monitor;
exsr MainProcess;
on-error;
ErrorHandler();
endmon;

//
// End Program
//
*inlr = *on;
return;
Scott Klement
Experienced User
Posts: 2711
Joined: Wed Aug 01, 2012 8:58 am
First Name: Scott
Last Name: Klement
Company Name: Profound Logic
City: Milwaukee
State / Province: Wisconsin

Re: Program Dump on Active Job

Post by Scott Klement »

Not what gets called for your ErrorHandler()? Is this within the same RPG program, or is this an external call?

If it's within the program, you can do something like this:

Code: Select all

  DUMP(A);
You have to do that within the same RPG program. I don't know of a way to make a dump from outside the program.

I took your code and fleshed it out a bit to try the DUMP(A)... this worked nicely for me:

Code: Select all

       //
       // *********************************************************************
       // Main Processing
       // *********************************************************************
       ctl-opt dftactgrp(*no);
       dcl-s x int(10) inz(0);

       //
       // Execute Main Procedure
       //
       monitor;
          exsr MainProcess;
       on-error;
          ErrorHandler();
       endmon;

       //
       // End Program
       //
       *inlr = *on;
       return;


       begsr MainProcess;
          // silly code to make a divide by zero error
          //   to test the error handler...
          x = 100 / x;
       endsr;


       dcl-proc ErrorHandler;

         dcl-pr QCMDEXC ExtPgm('QCMDEXC');
            cmd char(32768) const options(*varsize);
            len packed(15:5) const;
            igc char(1) const options(*nopass);
         end-pr;

         dcl-s cmd char(300);

         monitor;
            cmd = 'DSPJOBLOG OUTPUT(*PRINT)';
            QCMDEXC(cmd:%len(cmd));
            // other code to make it a PDF, etc
         on-error;
            // ignore errors
         endmon;

         monitor;
            DUMP(A);
            // other code to make it a PDF, etc.
         on-error;
            // ignore errors
         endmon;

       end-proc;
devinst
Profound User
Posts: 80
Joined: Mon Apr 20, 2009 11:26 am
First Name: Devin
Last Name: St. Germain
Company Name: Dupre Logistics, LLC
Phone: 337.314.2259
Address 1: 201 Energy Pkwy. Ste. 500
City: Lafayette
State / Province: Louisiana
Zip / Postal Code: 70508
Country: United States
Contact:

Re: Program Dump on Active Job

Post by devinst »

Thanks for the info Scott. My procedure was external but doing basically what you have in your code.
Below is my final solution. The external process will now send emails for the dump and job log pdf files being created.
Thanks Again.!!

//
// *********************************************************************
// Main Processing
// *********************************************************************
//
// Perform Main Processing Routine Monitoring for Errors
//
monitor;
exsr MainRoutine;
on-error;
Command = 'OvrPrtF File(QPPGMDMP) DevType(*AFPDS) +
ToSTMF(''/QOPENSYS/TempJobLogs/DUMP.PDF'') +
WSCST(*PDF) OVRSCOPE(*JOB)';
CmdLen = %len(Command);
QCmdExc (Command : CmdLen);
dump(a);
ErrorHandler();
endmon;
Scott Klement
Experienced User
Posts: 2711
Joined: Wed Aug 01, 2012 8:58 am
First Name: Scott
Last Name: Klement
Company Name: Profound Logic
City: Milwaukee
State / Province: Wisconsin

Re: Program Dump on Active Job

Post by Scott Klement »

Great, I'm glad that worked for you!

What I've seen in other shops is that the code that must be added to a program gets put into it's own routine and that routine gets put into a copy book. (the copy book lets you re-use it... since the DUMP(A) must be in the same module where the error occurs, you can't just bind it from a separate service program.)

So for example, you might take your code and make it like this:

Code: Select all

       dcl-proc InternalErrorHandler;

         dcl-pr QCMDEXC ExtPgm('QCMDEXC');
            cmd char(32768) const options(*varsize);
            len packed(15:5) const;
            igc char(1) const options(*nopass);
         end-pr;
      
         dcl-pr ErrorHandler ExtPgm('THE-PGM');
         end-pr;

         Command = 'OvrPrtF File(QPPGMDMP) DevType(*AFPDS) +
                  ToSTMF(''/QOPENSYS/TempJobLogs/DUMP.PDF'') +
                  WSCST(*PDF) OVRSCOPE(*JOB)';
         CmdLen = %len(Command);
         QCmdExc (Command : CmdLen);
      
         dump(a);
         ErrorHandler();

       end-proc;
Then that can go into a copy book, and all of your programs (I'm asuming you eventually want to do this everywhere) can just do this:

Code: Select all

       monitor;
          exsr MainRoutine;
       on-error;
          InternalErrorHandler();
       endmon;
 
       *INLR = *ON;
       Return;
              
       /COPY ERRHANDLE
At least, that's what I've seen in other shops (though, I must admit, they used fixed format RPG -- this was a while ago) ... thought it might be worth mentioning in case it's helpful to you.
Scott Klement
Experienced User
Posts: 2711
Joined: Wed Aug 01, 2012 8:58 am
First Name: Scott
Last Name: Klement
Company Name: Profound Logic
City: Milwaukee
State / Province: Wisconsin

Re: Program Dump on Active Job

Post by Scott Klement »

the definitions for Command and CommandLen should also be declared inside InternalErrorHandler (you don't want to have to define that by hand in each program) -- sorry, I forgot that part when I wrote the last message.

But, hopefully you got the idea, anyway.
devinst
Profound User
Posts: 80
Joined: Mon Apr 20, 2009 11:26 am
First Name: Devin
Last Name: St. Germain
Company Name: Dupre Logistics, LLC
Phone: 337.314.2259
Address 1: 201 Energy Pkwy. Ste. 500
City: Lafayette
State / Province: Louisiana
Zip / Postal Code: 70508
Country: United States
Contact:

Re: Program Dump on Active Job

Post by devinst »

An excellent idea Scott. One I will surly be implementing. Thanks again for all the help and advice.!!!
Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests