Page 1 of 1

GetProcessErrorFileName()

Posted: Wed Jun 06, 2018 12:39 pm
by tomok
I've got a process that uses a text file as a data source, with the name of the file to be processed one of the input parameters. If a user provides an incorrect file name the process obviously bombs and produces an error log file. I would like to get the name of that error log file using GetProcessErrorFileName() but it doesn't work. According to the IBM documentation, the value in this variable is only available after the completion of either the prolog, metadata or data tabs. My error is in the prolog but since it is fatal the prolog never finishes and the variable is empty. Does anyone know of a strategy for executing a process and getting the value from GetProcessErrorFileName() when a fatal error occurs in the prolog?

Re: GetProcessErrorFileName()

Posted: Wed Jun 06, 2018 2:00 pm
by lotsaram
Can't you just avoid the fatal error? Test for the existence of the source file and if it isn't there set datasource type to null and itemreject to create the error file. Then on the epilog pick up the error file name ...

Re: GetProcessErrorFileName()

Posted: Wed Jun 06, 2018 2:23 pm
by tomok
lotsaram wrote: Wed Jun 06, 2018 2:00 pm Can't you just avoid the fatal error? Test for the existence of the source file and if it isn't there set datasource type to null and itemreject to create the error file. Then on the epilog pick up the error file name ...
Thanks for the idea. That's what i was thinking I was going to have to do, I was just wondering if there was some sort of way to get the error log file name without resorting to that.

Re: GetProcessErrorFileName()

Posted: Wed Jun 06, 2018 2:58 pm
by tomok
How do I set the DataSourceType to null? NULL doesn't exist in TM1. I tried setting it to an empty string and the process just tries to use the file I have specified in the data source tab instead of not trying to open anything. Here is my code:

Code: Select all

sPath = CELLGETS('Global Variables', 'Value', 'Path to Hierarchy Files');

IF(FILEEXISTS(sPath | pFileName) = 0);
  DATASOURCETYPE= '';
  ITEMREJECT('File is missing');
  PROCESSBREAK;
ELSE;
  DATASOURCENAMEFORSERVER= sPath | pFileName;
ENDIF;

Re: GetProcessErrorFileName()

Posted: Wed Jun 06, 2018 4:58 pm
by tm123
Try this:

sPath = CELLGETS('Global Variables', 'Value', 'Path to Hierarchy Files');

IF(FILEEXISTS(sPath | pFileName) = 0);
DATASOURCETYPE= 'NULL';
ITEMREJECT('File is missing');
PROCESSBREAK;
ELSE;
DATASOURCENAMEFORSERVER= sPath | pFileName;
ENDIF;

Re: GetProcessErrorFileName()

Posted: Wed Jun 06, 2018 5:51 pm
by tomok
tm123 wrote: Wed Jun 06, 2018 4:58 pm Try this:

sPath = CELLGETS('Global Variables', 'Value', 'Path to Hierarchy Files');

IF(FILEEXISTS(sPath | pFileName) = 0);
DATASOURCETYPE= 'NULL';
ITEMREJECT('File is missing');
PROCESSBREAK;
ELSE;
DATASOURCENAMEFORSERVER= sPath | pFileName;
ENDIF;
That doesn't work, the process still tries to open the file, even though it doesn't exist. What I ended up doing is this:

Code: Select all

IF(FILEEXISTS(sPath | pFileName) = 0);
  DATASOURCETYPE= 'SUBSET';
  DATASOURCENAMEFORSERVER= '}Clients';
  DATASOURCEDIMENSIONSUBSET= 'All';
  ITEMREJECT('File is missing');
  PROCESSBREAK;
ELSE;
  DATASOURCENAMEFORSERVER= sPath | pFileName;
ENDIF;
What I am doing is setting the source to be a subset that I know always exists, whenever the file does not exist. The subset never gets processed because I send an error message to the log and then do a break. Not ideal but it does work.

Re: GetProcessErrorFileName()

Posted: Wed Jun 06, 2018 5:56 pm
by Alan Kirk
tomok wrote: Wed Jun 06, 2018 5:51 pm
tm123 wrote: Wed Jun 06, 2018 4:58 pm Try this:

sPath = CELLGETS('Global Variables', 'Value', 'Path to Hierarchy Files');

IF(FILEEXISTS(sPath | pFileName) = 0);
DATASOURCETYPE= 'NULL';
ITEMREJECT('File is missing');
PROCESSBREAK;
ELSE;
DATASOURCENAMEFORSERVER= sPath | pFileName;
ENDIF;
That doesn't work, the process still tries to open the file, even though it doesn't exist. What I ended up doing is this:

Code: Select all

IF(FILEEXISTS(sPath | pFileName) = 0);
  DATASOURCETYPE= 'SUBSET';
  DATASOURCENAMEFORSERVER= '}Clients';
  DATASOURCEDIMENSIONSUBSET= 'All';
  ITEMREJECT('File is missing');
  PROCESSBREAK;
ELSE;
  DATASOURCENAMEFORSERVER= sPath | pFileName;
ENDIF;
What I am doing is setting the source to be a subset that I know always exists, whenever the file does not exist. The subset never gets processed because I send an error message to the log and then do a break. Not ideal but it does work.
It didn't work because there's a bug in your logic; when you execute the ItemReject the Prolog stops executing and moves on, exactly as it does if you use the statement on a Data record. Therefore it never hits the ProcessBreak line, therefore it does not bypass the Metadata and Data tabs.

Because of the restrictive nature of GetProcessErrorFileName(), I never use the thing. Instead I use GetProcessErrorFileDirectory to get the path and append my own (usually more descriptive) file name. I then AsciiOutput that. That allows the ProcessBreak to execute.

Re: GetProcessErrorFileName()

Posted: Wed Jun 06, 2018 7:25 pm
by tomok
Alan Kirk wrote: Wed Jun 06, 2018 5:56 pm It didn't work because there's a bug in your logic; when you execute the ItemReject the Prolog stops executing and moves on, exactly as it does if you
That makes sense. I changed the logic to this and it works like I want it to now:

Code: Select all

Prolog:
IF(FILEEXISTS(sFile) = 0);
  PrologError = 1;
  ITEMREJECT('Hierarchy file ' | sFile | ' not found');
ELSE;
  DATASOURCENAMEFORSERVER= sFile;
ENDIF;

Code: Select all

MetaData (at the top):
IF(PrologError <> 0);
  PROCESSBREAK;
ENDIF;
The reason I need the process to finish is because I am accumulating stuff and posting it to the }ElementAttributes_}Processes cube after the process finishes, as well as accumulating an array of error log files (put into a global variable) that I parse through at the end of the chore to use as a source for sending the error files as attachments to an email. If the process bombs it doesn't finish and the update doesn't occur and I don't have that file name in my array.

I realize I could do something with EXECUTEPROCESS to control this stuff but I don't like to use that due to internal issues. Process changes have to go through a lot of red tape because of SOX but I can can change chores any time I want.

Re: GetProcessErrorFileName()

Posted: Wed Jun 06, 2018 7:51 pm
by Wim Gielis
Hi Tom,

Related coding can be found here, though it's not using GetProcessErrorFileName() but rahter ExecuteProcess of a generic process that tests the file.

Re: GetProcessErrorFileName()

Posted: Thu Jun 07, 2018 1:34 pm
by tm123
tomok wrote: Wed Jun 06, 2018 5:51 pm
tm123 wrote: Wed Jun 06, 2018 4:58 pm Try this:

sPath = CELLGETS('Global Variables', 'Value', 'Path to Hierarchy Files');

IF(FILEEXISTS(sPath | pFileName) = 0);
DATASOURCETYPE= 'NULL';
ITEMREJECT('File is missing');
PROCESSBREAK;
ELSE;
DATASOURCENAMEFORSERVER= sPath | pFileName;
ENDIF;
That doesn't work, the process still tries to open the file, even though it doesn't exist. What I ended up doing is this:

Code: Select all

IF(FILEEXISTS(sPath | pFileName) = 0);
  DATASOURCETYPE= 'SUBSET';
  DATASOURCENAMEFORSERVER= '}Clients';
  DATASOURCEDIMENSIONSUBSET= 'All';
  ITEMREJECT('File is missing');
  PROCESSBREAK;
ELSE;
  DATASOURCENAMEFORSERVER= sPath | pFileName;
ENDIF;
What I am doing is setting the source to be a subset that I know always exists, whenever the file does not exist. The subset never gets processed because I send an error message to the log and then do a break. Not ideal but it does work.
Insetad of ITEMREJECT, I use LOGOUTPUT, which a new TI Function (from Version 10.2.2x) and then I use PROCESSQUIT

IF ( FILEEXISTS ( sDataSourceFile ) = 0 ) ;
sReturnMessage = 'INVALID_DATA_SOURCE_FILE: ' | sDataSourceFile ;
CELLPUTS ( sReturnMessage , cubUserParams , sUserName , elmActionButtonMessage ) ;
LOGOUTPUT ( 'ERROR' , 'Process executed by user ' | sDisplayUserName | ' was teminated with error code: ' | sReturnMessage ) ;
DATASOURCETYPE= 'NULL';
PROCESSQUIT ;
ELSE ;
DATASOURCETYPE = 'CHARACTERDELIMITED' ;
DatasourceASCIIDelimiter = ',' ;
DATASOURCENAMEFORSERVER = sDataSourceFile ;
DATASOURCENAMEFORCLIENT = sDataSourceFile ;
ENDIF ;