企业绩效管理网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 431|回复: 4

ProcessError TI function doesn't work as expected

[复制链接]

79

主题

383

帖子

562

积分

高级会员

Rank: 4

积分
562
QQ
发表于 2014-3-20 02:59:13 | 显示全部楼层 |阅读模式
I have the following code in the Prolog for parameter input verification:

Code: IF ( DIMIX ( Dim, vVersion ) = 0 ) ;
    sMessage = 'Version ( ' | vVersion | ' ) does not exist.' ;
    ItemReject ( sMessage ) ;
    ProcessError ;
ENDIF ;

As expected, the message appears in the message log.
However, the process does not terminate, only the procedure terminates.
It then continues on to the Data procedure (no code in the Metadata procedure).
I have also tried ProcessBreak and ProcessQuit with the same result.
Anybody know of a method to reliably terminate a process from the Prolog?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

80

主题

402

帖子

587

积分

高级会员

Rank: 4

积分
587
QQ
发表于 2014-3-20 05:59:33 | 显示全部楼层
cdredmond wrote:I have the following code in the Prolog for parameter input verification:

Code: IF ( DIMIX ( Dim, vVersion ) = 0 ) ;
    sMessage = 'Version ( ' | vVersion | ' ) does not exist.' ;
    ItemReject ( sMessage ) ;
    ProcessError ;
ENDIF ;

As expected, the message appears in the message log.
However, the process does not terminate, only the procedure terminates.
It then continues on to the Data procedure (no code in the Metadata procedure).
I have also tried ProcessBreak and ProcessQuit with the same result.
Anybody know of a method to reliably terminate a process from the Prolog?

Greetings to you in Portland, my favourite city of the north-west which I may never see again but retain fond memories of.

I'm afraid it is working as expected; the problem is with the ItemReject line.

Strictly speaking ItemReject has no context in the Prolog but a lot of people do use it to generate an error log. (Hi Martin!) It's a quick and easy way of achieving that result and as long as IBM never pulls this undocumented feature, there's nothing wrong with doing that.

HOWEVER... when you do that the Prolog, which only has one "item" and that of a virtual kind, stops stone motherless dead and never executes any following statements including your ProcessQuit (etc) statement. Instead it just heads straight for the next tab with code on it, if any. (Same basic behaviour as you get if you encounter the statement on the Metadata or Data tab; none of the code following the ItemReject is executed and it moves straight to the next record (if any).)

You have a couple of alternatives:
(a) (My preferred one) Instead of using an ItemReject, get the error log file by using the GetProcessErrorFilename function, manually write the output to it, THEN ProcessQuit out of the sucker inside the If block; or
(b) Set a flag variable to True if there's an error, and check that in the first line of your Data tab. ProcessQuit if the flag is set to your True value. However I'd regard this as a waste of processor cycles; option (a) is far better.

Incidentally despite the v tag at the start I'm assuming that this really is a parameter that you're checking and not a variable. Obviously none of the variables will have a value in the prolog either, so it would always error out. (I generally tag parameters with a "p" to distinguish them from variables, and I've noticed that that's not an uncommon practice. But it's not a mandatory one obviously.)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 支持 反对

使用道具 举报

87

主题

373

帖子

564

积分

高级会员

Rank: 4

积分
564
QQ
发表于 2014-3-20 06:26:30 | 显示全部楼层
Alan Kirk wrote:You have a couple of alternatives:
(a) (My preferred one) Instead of using an ItemReject, get the error log file by using the GetProcessErrorFilename function, manually write the output to it, THEN ProcessQuit out of the sucker inside the If block; or
(b) Set a flag variable to True if there's an error, and check that in the first line of your Data tab. ProcessQuit if the flag is set to your True value. However I'd regard this as a waste of processor cycles; option (a) is far better.
Just to add another one, which is similar to Alan's option (b) and sounds similar to something you tried already:
(c) Set up an error message variable and populate with any error; call ProcessBreak; do the ItemReject as the last step in the Epilog:
Code: ### Prolog
sErrorMessage = '';
IF ( pVersion @= '' );
  sErrorMessage = 'pVersion was blank in ' | GetProcessName();
  ProcessBreak;
ENDIF;
# some more Prolog stuff goes here

### Epilog
# all your other Epilog comes first
IF ( sErrorMessage @<> '' );
  ItemReject ( sErrorMessage );
ENDIF;

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 支持 反对

使用道具 举报

74

主题

392

帖子

562

积分

高级会员

Rank: 4

积分
562
QQ
发表于 2014-3-20 07:15:10 | 显示全部楼层
Interesting that this was also discussed in some detail  just a few weeks back.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 支持 反对

使用道具 举报

66

主题

395

帖子

544

积分

高级会员

Rank: 4

积分
544
QQ
发表于 2014-3-20 07:15:15 | 显示全部楼层
Thank you to all three of you for your responses!  

lotsaram,
Thanks for linking to the other discussion which I did not find. It appears that Paul Simon is recommending what Alan Kirk calls option (b). While this does work, in this case, I am processing 10's to 100's of millions of cells and want to keep the processing time to a minimum.

rmackenzie,
Thank you for your clear explanation of the TI handling of ItemReject in Prolog and Epilog.
I use the same naming standard of 'p' for Parameters and 'v' for variables. The vVersion variable is actually inside a while loop that is extracting a values out of a comma delimited list one at a time to validate them.
I may totally lose you on this point, but at that risk: I coded MUMPS for about 8 years. One of the built-in functions it provides is $PIECE. This fuction allows you to identify a string, a delimiter (can be more than one character) and a position number. With this it will extract the 'n'th "piece" (substring) of information you want from the string. Boy how I wish TI could provide this and indirection!  But I digress...
Your option (c) worked the best for this situation. Here's what I did:
Code: # PROLOG #
# Declare Global Variables
NumericGlobalVariable ( 'PrologMinorErrorCount' ) ;
PrologMinorErrorCount = 0 ;
:
:
IF ( DIMIX ( Dim, vVersion ) = 0 ) ;
    sMessage = 'Version ( ' | vVersion | ' ) does not exist.' ;
    PrologMinorErrorCount = PrologMinorErrorCount + 1 ;
    ProcessBreak ;
ENDIF ;
:
:
# EPILOG #
# Quit if parameter input verification failed. #
IF ( PrologMinorErrorCount > 0 ) ;
    ItemReject ( sMessage ) ;
ENDIF ;
:
:


I have purposely used PrologMinorErrorCount so that all Prolog generated errors are handled consistently in the epilog. At least that's the idea at this point. It may change once I complete my unit testing of the error handling.

You guys were all a great help!
Thanks!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|企业绩效管理网 ( 京ICP备14007298号   

GMT+8, 2018-9-23 03:07 , Processed in 0.230351 second(s), 17 queries , Memcache On.

Powered by Discuz! X3.1 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表