RPG ILE ending program properly on an error

55 pts.
Tags:
RPG
RPG ILE
Hello, Could someone please help me with this? 1. I have an ever running job that calls a particular ILE program (PGM A) to do some XML parsing and composing. 2. PGM A calles another program PGM B (which in turn has modules MOD B, MOD C and a NOMAIN module MOD D binded to it). 3. PGM A parses the input XML and composes an output XML based on output generated in PGM B. If everything goes fine, I guess we are OK. But I am concerned about what would happen if PGM B or one of the modules get an error. I need to handle this error and give back info back to PGM A so that I can compose Error Info on the Output XML. Using Link List 1. Initially, I had plans to use Link Lists (because I wanted dynamic storage and not change array DS dimensions in future) to store output generated in PGM B. Then when I thought out "What if something goes wrong and I am not able to deallocate the memory allocated for the Link List", I hesitated a bit. It would have been easy if PGM B was on a separate activation group, but then I wouldn't be able to use Link list at all. But if I have everything on the same activation group, I can't use error handling features like Exit() function in C or the ILE API's because I believe they end everything upto the control boundary - it ended my job as well when I used it once while testing. 2. So, I took a copy of the source and used Array DS (although I don't prefer this one) instead of Link List. And put PGM B in a *NEW activation group. - I am not sure if using *NEW is a good idea as I have heard it affects performance. - So now PGM B is in a new activation group everytime it gets called. I coded C function Exit() to handle any uncaprtured errors - although it might really not be required since I guess the system will anyway release resources when the activation group ends. My question here is: Is there any way I can have both PGM A and PGM B in the same activation group and use some API/ some logic that I could use to end normally (everytime) upto PGM B on an error (without having to use *NEW activation) and pass back control to PGM A to generate the Error XML. Its because I am not really sure with *NEW activation group affecting performance and that I would love to use dynamic link lists. I hate the idea of having to pass a Dimension 200 (I might need even more probably) array DS as parameter and in future having to increase it. Looks old fashioned and rigid to me. Please help. Thanks, Ananthan

Answer Wiki

Thanks. We'll let you know when a new response is added.

Hi,

There is many way s to attack your problem. IMO, the simplest way is to code in PGM B a *PSSR in each procedure and take care of any error and return that error to PGM A.

If you don’t need to know the exactly error on PGM B (just that it finished on error) you can use the (E) extender on CALLP and %Error.

BTW, *NEW always can impact on performance. Each time the program is called/ended an activation group is created/deleted which cause overhead.

For your Link List question, you can use User Spaces to store results (if the result is less than 16MB!) or just pass a Pointer allocated on PGM A with a minimum storage that can be reallocated on PGM B as needed. If anything goes wrong in PGM B you can release storage with no problem.

Regards,
Wilson

Discuss This Question: 6  Replies

 
There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when members answer or reply to this question.

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy
  • Compengr2003
    Thanks a lot Wilson for your response. I would like to clarify something - when I mean error, it could be both hard errors or validation errors (like policy state not valid etc). In the latter case, *PSSR would not work. To handle exception errors, I coded a *PSSR in PGM B so that any exceptions errors down the lane (in PGM B or its modules) get percolated and handled in PGM B and I can give a generic message "Module ended abnormally". Or I could use the logic same as below. For validation errors (say I set an error flag FLG1 ON when one occurs), I am not sure about the best way to return control to PGM B (from other modules) because then I will have to code logic in each of the sub procedures to process only if FLG is *OFF (so that subsequent procedures do not get executed if an error (exception or validation error) occurred in a previous procedure). ****************** Proc1 B Proc1 PI /Free If FLG1 = *Off; ................... ................... Proc2 ( Parm1: Parm2 ); ................... ................... EndIf; /End-Free Proc1 E ****************** This can get me around back to mainline of PGM B (and then back to PGM A) but doesn't appeal to me much (although I can get my program done and move forward). Is there a better and easier way to get this done. Not sure if I am confusing you or getting myself confused.
    55 pointsBadges:
    report
  • bogeybetsy
    You don't have to enclose Proc 2 in between If-EndIf statements. You can just insert logic that would return to the calling program anywhere you want. For example: ****************** Proc1 B Proc1 PI /Free If FLG1 = *Off; // code here message to pass back, set on LR, // or anything else you want... Return; EndIf ………………. ………………. Proc2 ( Parm1: Parm2 ); ………………. ………………. /End-Free Proc1 E ******************
    560 pointsBadges:
    report
  • bogeybetsy
    Sorry, the If statement should be: If FLG1 = *On . . . Regards, Allan
    560 pointsBadges:
    report
  • Compengr2003
    Thanks Bogeybetsy. The issue here is that just a return would not help me because the procedures are nested to many levels - so just return will return me to the procedure just up the list and not exit out of the program and hence I will still have to code logic to check for error before executing each and every procedure. As mentioned earlier, I can't use API or C functions because then the program has to be on a different activation group so that the calling program does not also end.
    55 pointsBadges:
    report
  • WilsonAlano
    Ananthan, If you use a named activation group you can use C o ILE APIs in your pogram (PGMB in this case). It's not necessarily on another Activation Group. To get right out of a Service Program you can send an escape message to your call stack (QMHSNDPM) and your PGMB or PGMA can receive that message and take the appropriate action. So PGM A must run in a named activation group, PGM B can be *Caller or the same named activation group as PGM A. Each validation procedure can send a message to itself to cause PGM B to fail and PGM A can receive the percolated message to take action. I hope it can help you. Regards, Wilson
    2,600 pointsBadges:
    report
  • Eeklipzz
    First and foremost, a program should be thoroughly tested by both the programmer and a user for bugs before the program is put into production... *PSSR is a way that this can be done, but it is a potentially unefficient way of doing this... 1. Create an error handling procedure... ... in an externally described service program (or if you want to throw the future to the wind, hard code your procedure in the program) that handles putting the error message on the screen. example: putErrorMessage(). Set it up based on your particular company, or usage. Language settings can be passed in as parms... or whatever... Specifically, make it so that you can pass in an error code variable... example: putErrorMessage( <MSGF ID> : xxxxx : xxxx ). the xxxx in this example are whatever other parms you need to pass in. 2. Next, come up with a strategy... Program 2: You will want to put your error handling after every chance that the program has to bomb. example: // I'm assuming that you know how to define a char variable named message id if field = *blanks; messageID = '<MSGF ID>' ; return messageID; endif; Make sure that you have set up your program 2 to be able to pass this variable as a parameter. Additionally, it should also be included in the call to this program (unless you set the parameter options, as *omit or *nopass). Program 1: Call the program then immediately test for error messages... see example below: dow something; call program2 ( xxxxxxxx : xxxxxxxxxx ) if messageID > *blanks; putErrorMessage( xxxxxx : messagID) endif; enddo; 3. Build MSFG's for every possible error that would occur (that you know of) 4. Test test test!!!!! hope this helps. later, Luke
    130 pointsBadges:
    report

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to:

To follow this tag...

There was an error processing your information. Please try again later.

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy

Thanks! We'll email you when relevant content is added and updated.

Following