× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



Rich,

Have you tired call stack entry of '*' and count of 3?

Charles Wilt
iSeries Systems Administrator / Developer
Mitsubishi Electric Automotive America
ph: 513-573-4343
fax: 513-398-1121
 

> -----Original Message-----
> From: rpg400-l-bounces@xxxxxxxxxxxx
> [mailto:rpg400-l-bounces@xxxxxxxxxxxx]On Behalf Of Rich Duzenbury
> Sent: Thursday, March 17, 2005 2:13 PM
> To: RPG400-L unknown
> Subject: Proper way to die...
> 
> 
> Hey all,
> 
> I'm trying to figure out the correct way to throw an exception from an
> RPGLE program.  
> 
> I'm working on a program where I need to use the profile 
> handle api's to
> become another user for a short time.  Should any of the api 
> calls fail,
> I want to signal an exception, and if the new user is active, be sure
> that it's priviliges get dropped.
> 
> (See test code below).
> 
> I'm calling QMHSNDPM to signal the exception, and I've 
> wrapped it into a
> procedure to make it easier to call, as in die('Uh-oh something bad
> happened').
> 
> In the call to the send program message api, if I set the call stack
> entry to '*', and the call stack count to 0, then the message is:
> 
> Message ID: RNQ0202
> Type: Inquiry
> Sev: 99
> 
> The call to 'DIE' ended in error.
> 
> RPG procedure ZZZ_PH in program LIB/ZZZ_PH at statement 9700 call
> program or procedure DIE which ended in error.
> 
> This is not terrible, as the program and statement number are 
> listed in
> the second level text, BUT, I really need the message to be:
> 
> The call to ZZZ_PH ended in error.
> 
> Mainly because I might have a hundred programs using the die 
> procedure,
> and It would be much easier to debug if the _caller_ of die 
> is listed in
> the first level text.
> 
> So, I started playing around with the call stack entry and the call
> stack count.
> 
> In the case where the call stack entry is the name of the program
> ('ZZZ_PH') and the call stack count is set to zero, I get the same
> results as above, namely an RNQ0202 inquiry, sev 99, and the 
> same text.
> 
> In the case where the call stack entry is the name of the program, and
> the call stack count is set to one, I then receive a much different
> result.  
> 
> In this case, I receive no inquiry message, and the program returns to
> the command line with the following error listed at the bottom of the
> screen:
> 
> Message CEE9901
> Type INFO
> 
> Application error.  CPF9898 unmonitored by ZZZ_PH at statement *N,
> instruction x'0000'.
> 
> Then application ended abnormally because an exception 
> occurred and was
> not handled.
> 
> So, what is the proper way to die, such that the _caller_ of the die
> procedure is listed in the first level text?  Can it be done?
> 
> Thank you.
> 
> 
>      h option(*srcstmt:*nodebugio) dftactgrp(*no) bnddir('QC2LE')
> 
>      D  userid         s             10a
>      D  password       s             10a
>      D  msg            s             50a
>      D  rc             s             10i 0
>      D  p_abend        s               *   procptr
>      D  token          s               *
>      D  feedback       s             12a
> 
>       * Profile handle 1, our current profile handle
>      D ph1             ds                  qualified
>      D  handle                       12a
>      D  loaded                         n
>      D  active                         n
> 
>       * Profile handle 2, our current profile handle
>      D ph2             ds                  qualified
>      D  handle                       12a
>      D  loaded                         n
>      D  active                         n
> 
>       * universal api error data structure
>      D error           ds                  qualified
>      D  provided                     10i 0
>      D  available                    10i 0
>      D  msgid                         7a
>      D  rsvd                          1a
>      D  msgdta                       80
> 
>       * program status data structure
>      D sds            sds                  qualified
>      D  proc             *proc
> 
>       * get profile handle
>      D getph           pr
> extproc('QsyGetProfileHandle')
>      D  handle                       12a
>      D  userid                       10a   const
>      D  password                    512a   const options(*varsize)
>      D  pw_length                    10i 0 value
>      D  pw_ccsid                     10u 0 value
>      D  error                              likeds(error)
> 
>       * set profile handle
>      D setph           pr
> extproc('QsySetToProfileHandle')
>      D  handle                       12a
>      D  error                              likeds(error)
> 
>       * release profile handle
>      D rlsph           pr
> extproc('QsyReleaseProfileHandle')
>      D  handle                       12a
>      D  error                              likeds(error)
> 
>       * cancellation cleanup
>      D ceertx          pr                  extproc('CEERTX')
>      D  procedure                      *   procptr
>      D  token                          *
>      D  feedback                     12a
> 
>       * local cleanup routine
>      D cleanup         pr
> 
>      D die             pr
>      D  message                     512a   const options(*varsize)
> 
>      D whoami          pr                  extpgm('ZZZ_WHOAMI')
> 
>      C     *entry        plist
>      C                   parm                    userid
>      C                   parm                    password
> 
>       /free
> 
>           error.provided = %size(error);
> 
>           // Install cancel handler.  In the case that this code
>           // somehow crashes, this will ensure that cleanup is
>           // run and drops the priviliges of the passed in userid
>           p_abend = %paddr('CLEANUP');
>           ceertx(p_abend : token : feedback);
> 
>           whoami();
> 
>           // save our handle so we can restore it later
>           getph(ph1.handle : '*CURRENT' : '*NOPWD' : 6 : 0 : error);
>           if error.available > 0;
>               die('getph-nopwd Error: ' + error.msgid + ' ' +
>                     error.msgdta);
>           endif;
>           ph1.loaded = '1';
>           ph1.active = '1';
> 
>           // get the handle for the asked for userid/password
>           getph( ph2.handle : userid : password :
>                      %len(%trim(password)) : 0 : error);
>           if error.available > 0;
>                  die('getph-withpw Error: ' + error.msgid + ' ' +
>                    error.msgdta);
>           endif;
>           ph1.loaded = '1';
> 
>           // set profile to new handle
>           setph( ph2.handle : error);
>           if error.available > 0;
>               die('setph2 Error: ' + error.msgid +
>                             ' ' + error.msgdta);
>           endif;
>           ph1.active = '0';
>           ph2.loaded = '1';
>           ph2.active = '1';
> 
>           whoami();
> 
>           cleanup();
> 
>           whoami();
> 
>           *inlr = '1';
>       /end-free
> 
>       *
> 
> **********************************************************************
>       * Cleanup the handles and return to base handle
> 
> **********************************************************************
>       *
>      P cleanup         b
>      D cleanup         pi
> 
>       /free
>          dsply 'Cleaning up';
> 
>           // return to original profile if necessary
>           if ph2.active = '1';
>               setph( ph1.handle : error);
>           ph1.active = '1';
>           ph2.active = '0';
>           endif;
> 
>           if ph2.loaded = '1';
>               rlsph( ph2.handle : error);
>               ph2.loaded = '0';
>           endif;
> 
>           if ph1.loaded = '1';
>               rlsph( ph1.handle : error);
>               ph1.loaded = '0';
>           endif;
>       /end-free
>      P                 e
> 
>       *
> 
> **********************************************************************
>       * die - kill ourself
> 
> **********************************************************************
>       *
>      P die             b
> 
>      D die             pi
>      D  message                     512a   const options(*varsize)
> 
>      D  short_msg      s             50a
>      D  msgkey         s              4a
>      D  msgid          c                   'CPF9898'
>      D  msgf           c                   'QCPFMSG   *LIBL     '
> 
>      D sndpgmmsg       pr                  extpgm('QMHSNDPM')
>      D  msgid                         7a   const
>      D  msgf                         20a   const
>      D  msgdta                      512a   const options(*varsize)
>      D  msgdtalen                    10i 0 const
>      D  msgtype                      10a   const
>      D  callstkent                   10a   const
>      D  callstkcnt                   10i 0 const
>      D  msgkey                        4a
>      D  error                              likeds(error)
> 
>       /free
>          sndpgmmsg( 'CPF9898' : 'QCPFMSG   *LIBL' :
>                     %trim(message) : %len(%trim(message)) :
>                     '*ESCAPE' :
>                     sds.proc :
>                     0 :
>                     msgkey :
>                     error);
>       /end-free
>      P                 e
> --
> Regards,
> Rich
> 
> Current Conditions in Des Moines, IA
> Overcast
> Temp 51.8F
> 
> 
> -- 
> This is the RPG programming on the AS400 / iSeries (RPG400-L) 
> mailing list
> To post a message email: RPG400-L@xxxxxxxxxxxx
> To subscribe, unsubscribe, or change list options,
> visit: http://lists.midrange.com/mailman/listinfo/rpg400-l
> or email: RPG400-L-request@xxxxxxxxxxxx
> Before posting, please take a moment to review the archives
> at http://archive.midrange.com/rpg400-l.
> 
> 


As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.