No announcement yet.

Data Source Exit Program error

  • Filter
  • Time
  • Show
Clear All
new posts

  • Data Source Exit Program error

    I created a data source with a pre-execution program. I received this error when trying to create a Grid Widget over the data source.

    CPF3303 - Error CPF3303 on attempt to call data source exit program CRTDEVLIST
    Help Text
    Error occurred in conjunction with data retrieval for data source ID 1047.

    The program has a PI of

    dcl-pi *n;
      gDSid packed(15:2) options(*nopass);
      gErrorText char(128) options(*nopass);

  • #2
    Try changing your gDSid field to packed(15:5), to align with what's described here:


    • #3
      I saw that and changed my PI to
       dcl-pi *n;
      gDSid packed(15:5) options(*nopass);
      gErrorText varchar(128) options(*nopass);
      Still getting the CPF3303.
      The program I'm calling runs WRKCFGSTS CFGTYPE(*DEV) OUPTUT(*PRINT) and then copies that to a temp file.

      CPF3303 seems to be related to spooled files?

      The job log shows
      HTML Code:
      File QSYSPRT not found in job 253417/QTMHHTTP/VALENCE6P.
      Object DEVLIST in QTEMP type *FILE created.
      1 objects duplicated.
      Member DEVLIST file DEVLIST in QTEMP cleared.
      File QSYSPRT not found in job 253417/QTMHHTTP/VALENCE6P.
      Trigger program or external routine detected an error.
      Trigger program or external routine detected an error.
      File QSYSPRT not found in job 253417/QTMHHTTP/VALENCE6P.


      • #4
        Yeah, that's a curious CPF message. I was thinking maybe it was a typo, but since you've clarified your exit program is generating a spool file it makes a bit more sense...

        This doesn't sound like it's related to Valence, at least not directly. The data source program is trapping the error coming back from your exit program so the job doesn't go into MSGW, and then letting you know the error code. So if you can't glean enough info from the job log you're probably going to need to start a service job on the CGI job getting the call and go into the debugger.

        You might try calling your program interactively first, that might be sufficient to replicate the error.
        Last edited by robert.swanson; 11-26-2021, 11:12 AM. Reason: added interactive suggestion


        • #5
          So it turns out the issue is directly related to what I'm trying to do.
          I'm creating a SPLF calling QCMDEXEC.
          Then I'm trying to access that via SQL & SYSTOOLS.SPOOLED_FILE_DATA and
          Delete the SPLF using DLTSPLF FILE(QSYSPRT) JOB(123456/username/QPRTJOB).
          This is where the error is coming from (interactively it works fine)

          So I'm using VVSESSDTA to get the IBMiUser. I was trying to use the jobNbr from PSDS, but that's not the job number i see on the actual spooled file.

          I'm not sure how to get the job number of the spooled file created...
          Job is QPRTJOB
          User is the Valence User
          But the job number doesn't match the CGI job?


          Last edited by gwilburn; 11-26-2021, 02:16 PM. Reason: Corrected


          • #6
            As long as the program(s) creating and retrieving the spool file is/are in the same call stack as the NAB data source program attempting to retrieve its data, the job number in the PSDS should be correct.

            Are you using some other job, separate from the CGI job, to generate the spool file? If that's the case you'll need the program/job creating the spool file to save the job# so it can be retrieved by the CGI job, i.e. via a session variable (vvUtility_saveSessVar, followed by vvUtility_getSessVar).

            We're off the rest of the day today. If you're still wrestling with this come Monday, shoot an email to support here and someone will get on a web call with you to have a look.


            • #7
              So this is the pre-execution program is a single pgm i wrote to create the data source.
              (I'm simply trying to get a list of devices and status - similar to Nitro i Admin)

              The program generates the output using this call:
              vvUtility_qcmd('WRKCFGSTS CFGTYPE(*DEV) OUTPUT(*PRINT)');
              Then runs the SQL statement to generate the file DEVLIST in QTEMP.
              sessDS = vvUtility_getSessVar(VVSESSVAR);
              sessId = %trim(sessDS.VVSESSID);
              sessUser = %trim(sessDS.VVIBMIUSER);
              jobName = %editc(psds.jobNbr:'X') + '/' + sessUser + '/QPRTJOB';
              Exec Sql Insert into QTEMP.DEVLIST
              SELECT :sessID,
              // JOB_NAME => '*',
              JOB_NAME => :jobName,
              SPOOLED_FILE_NAME => 'QSYSPRT'))
              WHERE SUBSTR(SPOOLED_DATA,23,4) = '*DEV'
              However, the job number does not match any of the CGI jobs. Not even close.

              Subsystem/Job User Number Type
              VALENCE6P QTMHHTTP 253423 BCI
              VALENCE6P QTMHHTTP 253424 BCI
              VALENCE6P QTMHHTTP 253425 BCI
              VALENCE6P QTMHHTTP 253727 BCI
              VALENCE6P QTMHHTTP 253779 BCI
              VALENCE6P QTMHHTTP 253780 BCI
              VALENCE6P QTMHHTTP 253781 BCI
              VALENCE6P QTMHHTTP 253782 BCI
              VBCH253422 QTMHHTTP 255579 BCH
              Spooled file attributes generated by the command:
              File Nbr Job User Number
              QSYSPRT 51 QPRTJOB GWILBURN 021576
              QSYSPRT 52 QPRTJOB GWILBURN 021576
              QSYSPRT 53 QPRTJOB GWILBURN 021576
              QSYSPRT 54 QPRTJOB GWILBURN 021576
              QSYSPRT 55 QPRTJOB GWILBURN 021576
              QSYSPRT 56 QPRTJOB GWILBURN 021576
              QSYSPRT 57 QPRTJOB GWILBURN 021576
              It seems like calling the command is using a job name of QPRTJOB and the associated job number.

              I'm perplexed.

              I'll put this in an email to support.


              • #8
                Okay, I see what's going on now. It turns out that whenever the current user of a job is overridden -- which is what happens inside Valence CGI jobs -- the IBM i OS automatically uses QPRTJOB to generate any spool files. This was news to me!


                Fortunately the solution is fairly simple. You can use the QSPRILSP API to retrieve the job info for the last generated spool file, then apply that to your SPOOL_FILE_DATA parameters.

                I whipped up a quick and dirty RPG program called SPLF_TEST to try this out...
                /copy qcpylesrc,vvHspec
                dcl-pi *n;
                  gDSid packed(15:5) options(*nopass);
                  gErrorText varchar(128) options(*nopass);
                dcl-pr getLastSplfID extpgm('QSPRILSP');
                  rcvVar char(1) options(*varsize);
                  lenRcvVar int(10) const;
                  fmtRcvVar char(8) const;
                  qusec likeds(QUSEC);
                /copy qcpylesrc,vvDspec
                /copy qsysinc/qrpglesrc,qsprilsp
                /copy qsysinc/qrpglesrc,qusec
                vvUtility_qcmd('WRKCFGSTS CFGTYPE(*DEV) OUTPUT(*PRINT)'); 
                GetLastSplfID(QSPL0100:%size(QSPL0100):'SPRL0100': qusec);
                vvOut_success(*on:'Spool file '+%trim(QSPSN03)+' was created by job '+

                Results in this response when compiled and called from the Test RPG Call app...


                • #9
                  THANKS!!! That did the trick.

                  If this helps anyone else... the job name needs to be defined like this (your text example above had the QSPJNBR00 and QSPJN00 reversed):

                  jobName = %trim(QSPJNBR00)+'/'+%trim(QSPUN00)+'/'+%trim(QSPJN00);
                  splNbr = QSPSNBR03;
                  splName = QSPSN03;

                  The spool number and spool name are also returned by that API - these are useful with SYSTOOLS.SPOOLED_FILE_DATA to ensure you're getting & deleting the exact spool file you create.

                  Thanks again!