|
On Thu, 2005-03-17 at 13:24 -0600, Holden Tommy wrote:
> you already have the program name from the psds... why not just do this:
>
> die('getph-nopwd Error In:' + sds.proc + error.msgid + ' ' +
> error.msgdta);
>
Tommy,
Thanks for the suggestion.
The low level messages in the joblog already indicate the program name:
4>> call zzz_ph (foo bar)
DSPLY USERID USERID
getph-withpw Error: CPF2204 FOO.
Function check. CPF9898 unmonitored by ZZZ_PH at statement
0000009700,
instruction X'0000'.
The call to DIE ended in error (C G D F).
It's simply that I'd like the message to indicate the _caller_ instead
of the DIE procedure:
The call to ZZZ_PH ended in error (C G D F).
Some folks won't bother to review second level text...
> Thanks,
> Tommy Holden
>
>
> -----Original Message-----
> From: rpg400-l-bounces@xxxxxxxxxxxx
> [mailto:rpg400-l-bounces@xxxxxxxxxxxx]On Behalf Of Rich Duzenbury
> Sent: Thursday, March 17, 2005 1: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
--
Regards,
Rich
Current Conditions in Des Moines, IA
Overcast
Temp 55.4F
Winds out of the North at 13mph
at http://archive.midrange.com/rpg400-l.
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2025 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.