Interrogating the 'error' value from an FileOpen statement

 

Can't figure out why this happens!

I have a routine to check the integrity of my orders.  [If I have previously been unable to close orders after delays and retrys then details are written to file and dealt with here]

So in 99.9% of occasions (give or take a little) I would not expect to find a file present


my Log file records the following:-

91200 2013.01.03 16:19:26 IOC - Enters Integrity_Orders_Check

91201 2013.01.03 16:19:26 IOC - error = 4103

91202 2013.01.03 16:19:26 IOC - error: 4103 cannot open file My_FileClose_Handle =-1


I enter the routine OK (91200 above)

The error code is 4103 - according to statement 91201 above

I would then expect to see ..... "IOC - No errors NO file exists"  rather than the message above - i.e. 91202

the routine goes on to execute correctly as a result of the last statement below.

Just appears to be me  misunderstanding how 'error' is interrogated (error is defined globally as int)


Any ideas please ??

string Integrity_Orders_Check()
{  string Local_Test_Flag = "YES";
   string problem_string[100]; 
   temp_string          = "Blank";
   int My_Backup_Handle = 0;
   problems[0][0]       = 0;
   if ( Local_Test_Flag == "YES" ) write_to_new_log(91200,"IOC - Enters Integrity_Orders_Check","YES");
   My_FileClose_Handle = FileOpen("My_UN_Close_Log_"+Symbol()+".txt", FILE_CSV|FILE_READ, "|");   // located in Check_Log_File
   error = GetLastError();    //*************************EXPECT NO FILE ***************** ONLY PRESENT IF UNABLE TO CLOSE ORDERS
   string st_91202 = "IOC - error: "+error+" "+ErrorDescription(error)+" My_FileClose_Handle ="+My_FileClose_Handle;
   string st_91203 = "IOC - No errors NO File exists";
   if ( Local_Test_Flag == "YES" ) write_to_new_log(91201,"IOC - error = "+error,"YES");
   if (error != 4103 ) write_to_new_log(91202,st_91202,"YES");
   if (error == 4103 ) write_to_new_log(91203,st_91203,"YES");
   int i1 = 0;    // read any problems from file
//..........................................................................................................................
   if( My_FileClose_Handle > -1 )      // "File Does Exist";
 

peterhw1:

the routine goes on to execute correctly as a result of the last statement below.

Just appears to be me  misunderstanding how 'error' is interrogated (error is defined globally as int)

Don't look at GetLastError(), unless an error occurs. Test the handle first.
 
peterhw1:

Can't figure out why this happens!


I would then expect to see ..... "IOC - No errors NO file exists"  rather than the message above - i.e. 91202

the routine goes on to execute correctly as a result of the last statement below.

Just appears to be me  misunderstanding how 'error' is interrogated (error is defined globally as int)

OK,  I can foresee a scenario where what you describe could happen.  Part of the scenario is due to you using a global for error,  how do you know that the value of error isn't changed outside of this function ?  perhaps during the call of    write_to_new_log()   ?  so before this call error is == 4103  so 91201 is correct,  then error is changed and it is now != 4103  so 91202 is printed . . . .


So I would suggest the following, use local variables for error values,  only call GetLastError() when there is actually an error . . .

   My_FileClose_Handle = FileOpen("My_UN_Close_Log_"+Symbol()+".txt", FILE_CSV|FILE_READ, "|");   // located in Check_Log_File

   error = GetLastError();    //*************************EXPECT NO FILE ***************** ONLY PRESENT IF UNABLE TO CLOSE ORDERS

   //  why call GetLastError() without checking if your handle is -1 first ?  if it's not -1 there is no error . . .

  . . .  add a debug option to print the error in raw format eliminating your logging functions . . .

if(Debug) Print("Last error # ", error);

 You enable this by setting an extern bool Debug to true and disable it y setting false.  this takes your functions out of the equation and reduces the area of confusion.

 

I usually open file only once for the rest of execution (in Init() or in Start() usually the later), rather than open then close several hundred times and deal with file problem.

Later I close it in Deinit.

<EDIT : and make sure to zeroing handle in init or deinit) 

//--- global variable
int handle = 0;

if (handle == 0)
   {
   handle = FileOpen (....);

   if (handle == -1)
     {
     handle = 0;
     Print ("you have file error");
     }
   }
   
   ...
   ...
   ...


if (handle > 0)
   {
   //--- file read - write here
   //--- if here are error that indicate file does not exist : 1> try to open again 2> get out ans set handle = 0
   
   }
 
phi.nuts:

I usually open file only once for the rest of execution (in Init() or in Start() usually the later), rather than open then close several hundred times and deal with file problem.

Later I close it in Deinit.

When does the file(s) get closed if MT4 crashes ?
 
RaptorUK:
When does the file(s) get closed if MT4 crashes ?

Regardless where file close is located. No it won't get closed if crashes, but can't open it as well - I assume the crash wipe everything out as well.

 
phi.nuts:

Regardless where file close is located. No it won't get closed if crashes, but can't open it as well - I assume the crash wipe everything out as well.

The point is that if a file is closed as soon as it is no longer needed to be open it has less risk of being open at the time of a crash . . . .  if I am working with 5 files and keep them open then they are open all the time while the EA runs, any crash during that long time period will result in 5 files being left open.
 
RaptorUK: When does the file(s) get closed if MT4 crashes ?

Seeing as I've gone from using GlobalVariableSet() to using Files lately. Your question above was of interest to me as well because I don't close my file either. I just ran a test within the strategy tester. The Expert created a new file as expected. Then I Control-Alt-Delete and Terminated the terminal [while the test was still running]. When I tried to Open the File, it allowed me. Also, it contained Data.

Well dunno if an actual crash makes a difference. But I think it'll save the last File-Write information. Also, the File-Flush function, could be an alternative to saving without closing and re-opening every tick. Ps> The file-type above is .csv dunno if that makes a difference either.

 
RaptorUK:

OK,  I can foresee a scenario where what you describe could happen.  Part of the scenario is due to you using a global for error,  how do you know that the value of error isn't changed outside of this function ?  perhaps during the call of    write_to_new_log()   ?  so before this call error is == 4103  so 91201 is correct,  then error is changed and it is now != 4103  so 91202 is printed . . . .


So I would suggest the following, use local variables for error values,  only call GetLastError() when there is actually an error . . .

  . . .  add a debug option to print the error in raw format eliminating your logging functions . . .

 You enable this by setting an extern bool Debug to true and disable it y setting false.  this takes your functions out of the equation and reduces the area of confusion.


many thanks - understand what you say and appreciated
 
phi.nuts:

I usually open file only once for the rest of execution (in Init() or in Start() usually the later), rather than open then close several hundred times and deal with file problem.

Later I close it in Deinit.

<EDIT : and make sure to zeroing handle in init or deinit) 


I understand.

I maintain a log file - loads of data recorded for my own debugging and analysis.  I close this every hour and open a new file (with time in file name for identification).  If this is lost it doesn't really matter. I CLOSE in De-init as you suggest if the EA is closed.

In the case of my example here I only open / write to a file in the event that I have been unable to close an order.  If for example I have 4 orders to close at the same time then I check that each has been closed.  If after several iterations the order can not be closed then I write the details to the file. 

If there is no file there is no problem and hence I don't open & close files hundreds or thousands of times. (I am still operating on a test account and this occurrence is pretty infrequent - I'd expect it to be even less frequent on a live account))

If there is a problem then the file will exist containing 1 or more orders (for the current symbol).  I then try to close each of the orders again.  If successful then I delete the file and do NOT open again (i.e. there is no file).  If I still have problem then the file remains in place for the next iteration etc.

 
ubzen:

Seeing as I've gone from using GlobalVariableSet() to using Files lately. Your question above was of interest to me as well because I don't close my file either. I just ran a test within the strategy tester. The Expert created a new file as expected. Then I Control-Alt-Delete and Terminated the terminal [while the test was still running]. When I tried to Open the File, it allowed me. Also, it contained Data.

Well dunno if an actual crash makes a difference. But I think it'll save the last File-Write information. Also, the File-Flush function, could be an alternative to saving without closing and re-opening every tick. Ps> The file-type above is .csv dunno if that makes a difference either.

I guess it depends of what you are doing with your files,  I'm currently coding some stuff to save arrays to files but the file will only be updated when there is new information to be saved not on every tick, so for me the overhead of opening and closing the files each time is not an issue,  if you are writing to the file(s) on each tick then it may be a different matter.
Reason: