none
Invalid path or file name

    Question

  • HI, I was just wondering under what circumstances either FILE() or ADIR() func returns following error in VFP?

    ErrorNo: 202, Invalid path or file name.


    Cheers!

    Friday, January 11, 2013 12:57 PM

Answers

  • Looks like you're using ASTACKINFO for the progsequence, then also put in the array elements (column 5) telling the lineno, that would be a major new info about which line of FILEEXIST is erroring, it could be FILE, it could be ADIr, it could even be JUSTPATH. See into your error handler code writing these log entries. 

    I've shown you can pass in very invalid paths (eg with more than one colon) into FILE() and it will not throw an error, but return .F., but only the value of tcFileName at that stage would help you see what causes the error, and how you could handle that. It might be anything else completely unexpeced like line feed, tab, chr(0) - anything even I didn't thought of yet, might also be no string at all, eg .NULL. or .F.

    Bye, Olaf.

    PS: It's not very easy and straight forward to get variable values in your error report log, as local variables are of course local, your error handler doesn't have the tcFileName in scope, so it can't log it, so you have to do that beforehand, so use STRTOFILE() to write the tcFileName value, no matter what it is and then continue with the rest of the function.

    Monday, January 14, 2013 8:28 AM
  • Hm, Lineno should be in the stack info array, no matter if you turn on or off debug info. LINENO() also works without debug info checked.

    So even if ASTACKINFO would be empty in column 5, passing in LINENO() as one parameter of the ON ERROR definition into the error handler will at least tell you the line of error at the current stack level.

    Turning off debug info just causes MESSAGE(1) to stop returning the current source code, and column 6 of the stack info array will not have source lines in it.

    Bye, Olaf.

    I tested it: Without debug info ASTACKINFO does not even return line numbers, but LINENO() tells you the line number even without debug info embedded.

    Besides: Theere is no functional difference between an exe with or without debug info. I never experienced any problem due to debug info.



    Tuesday, January 15, 2013 6:17 PM
  • I just have to correct Olaf's post:

    LINENO() used in ON ERROR requires debug info otherwise it returns 0. VFP interpreter cannot know the line number of code when an error occurs if the debug info is missing.

    LINENO() in a standard code does not require debug info and it is handled as a numeric constant during the compilation.

    Please test it again :-)

    • Marked as answer by eCasper Wednesday, January 16, 2013 5:34 AM
    Tuesday, January 15, 2013 10:06 PM
    Moderator

All replies

  • An invalid path or file would cause that, of course.

    So what were the parameter values of the calls? The code itself is insufficient to understand the problem, you also will need the variable values, as they exactly were, when the error occured.

    For example: invalid is using / in file names, using \\ more than once at the beginning, : more than once after a a drive letter, using ? or *, even if the file system allows unicode chars. Those * and ? are allowed in the fileskeleton parameter of ADIR, but not as the parameter of FILE(). A path beginning with ...\ instead of .\ or ..\ also isn't valid, and many more other chars or combinations or positions of chars are invalid. Is there perhaps some char in your parameter values looking ok, but being some other codepage char not allowed for file names?

    To get to the root cause you will need to write the parameter values causing the error into the error log.

    Bye, Olaf.


    Friday, January 11, 2013 1:21 PM
  • Hi Olaf, There is a user who has about 120MB of error log file with similar entries. As you can see below, probably it is the FILE function throws the error as 202 error has been suppressed for ADIR. Sometimes back we had to suppress the error for ADIR because of this user only.

    Now I realized they do have a problem with the environment which I cannot figure it out.

    As you suggested I need to write parameter values to the error log in order to see if there any such characters in the file path.

    Q1: However do you think there are such invalid characters which are valid to defined in the OS but invalid with VFP functions?

    Q2: How do I find unicode characters (if that is the case) in the file path (once it has written to log file)?

    LPARAMETERS tcFileName
    IF VARTYPE(tcFileName) # 'C' OR EMPTY(tcFileName)
    	RETURN .F.
    ENDIF
    LOCAL ARRAY laHiddenFile(1)
    LOCAL llFileExist
    *-- If wildcards are passed it doesn't support FILE() funtion.
    *-- Therefore it uses ADIR() function to return whether the file exist
    IF EMPTY(JUSTPATH(tcFileName)) AND !(("*" $ tcFileName) OR ("?" $ tcFileName))
    	*-- No error handler for FILE(), because it doesn't fail for invalid path or file name
    	llFileExist = FILE(tcFileName,1)
    ELSE
    	TRY
    		llFileExist = ADIR(laHiddenFile, tcFileName, 'H') > 0
    	CATCH TO loError
    		llFileExist = .F.
    	ENDTRY
    	*-- Suppress invalid path or file name error
    	IF VARTYPE(loError) = "O" AND loError.ErrorNo <> 202
    		ERROR (loError.ErrorNo)
    	ENDIF
    ENDIF
    RETURN llFileExist

    Cheers!

    Friday, January 11, 2013 1:59 PM
  • >There is a user who has about 120MB of error log file with similar entries

    Error log entries similar to what? Similar to each other? Can you post one of these entries? Does it report the line of error and the value of tcFileName when the error happens?

    Assumed the error does not happen in this code at all, assumed it happens after your function has been used and returns .T. for a file skeleton, which nevertheless is no file name. That would explain it, for example. You answer .T. to a value of tcFilename="*.dbf", if there is a dbf with any name in the current directory, because you branch into using ADIR(), but when "*.dbf" is used as a file name, most commands and functions will report "file not found", as there of course no file *.dbf. Your extension of the file function might make sense, but then it also has to be used wisely.

    So add to your error handling routine to include the values of tcFileName, if it does not do so yet, and let it include the line of error via PROGRAM() and LINENO() if it does not yet do so. And if it does, what is the line of error? You seem to be unsure where it actually happens, so find out.

    Bye, Olaf.

    Friday, January 11, 2013 3:00 PM
  • Hi Olaf, Following is one of the entries that I was refering to and FileExist is the method that I posted on my previous reply.

    I'm not sure whether if I will be able to track the line no in the exe using LINENO() but I will try that too.
    However do you see any other command/func. will return this error by assuming error emerged within above program?

    FYI:tcFileName contains fullpath to the file.

    <ftmperrorloginfo>
    	<datetime>21 November 12, 08:43:04</datetime>
    	<appver>*.**.**</appver>
    	<projno>***-****</projno>
    	<userid>**</userid>
    	<errorno>202</errorno>
    	<actor>****.FILEEXIST</actor>
    	<dscrptn>Invalid path or file name.</dscrptn>
    	<usermsg/>
    	<progsequence>
    13.
    12.
    11.l:\****\***\***.vct
    10.
    9.l:\****\***\**.vct
    8.
    7.
    6.
    5.l:\***\****\****.scx
    4.l:\**\****\***.scx
    3.***.fxp
    2._***.fxp
    1.l:\****\***\*****.exe</progsequence>
    </ftmperrorloginfo>


    Cheers!

    Monday, January 14, 2013 4:44 AM
  • Looks like you're using ASTACKINFO for the progsequence, then also put in the array elements (column 5) telling the lineno, that would be a major new info about which line of FILEEXIST is erroring, it could be FILE, it could be ADIr, it could even be JUSTPATH. See into your error handler code writing these log entries. 

    I've shown you can pass in very invalid paths (eg with more than one colon) into FILE() and it will not throw an error, but return .F., but only the value of tcFileName at that stage would help you see what causes the error, and how you could handle that. It might be anything else completely unexpeced like line feed, tab, chr(0) - anything even I didn't thought of yet, might also be no string at all, eg .NULL. or .F.

    Bye, Olaf.

    PS: It's not very easy and straight forward to get variable values in your error report log, as local variables are of course local, your error handler doesn't have the tcFileName in scope, so it can't log it, so you have to do that beforehand, so use STRTOFILE() to write the tcFileName value, no matter what it is and then continue with the rest of the function.

    Monday, January 14, 2013 8:28 AM
  • Yes I do use ASTACKINFO(). Probably I need to turn on the debugging mode to get the line number out of ASTACKINFO(). I was just wondering what difference will add to the application by doing that apart from the exe file size?


    Cheers!

    Tuesday, January 15, 2013 12:48 PM
  • Hm, Lineno should be in the stack info array, no matter if you turn on or off debug info. LINENO() also works without debug info checked.

    So even if ASTACKINFO would be empty in column 5, passing in LINENO() as one parameter of the ON ERROR definition into the error handler will at least tell you the line of error at the current stack level.

    Turning off debug info just causes MESSAGE(1) to stop returning the current source code, and column 6 of the stack info array will not have source lines in it.

    Bye, Olaf.

    I tested it: Without debug info ASTACKINFO does not even return line numbers, but LINENO() tells you the line number even without debug info embedded.

    Besides: Theere is no functional difference between an exe with or without debug info. I never experienced any problem due to debug info.



    Tuesday, January 15, 2013 6:17 PM
  • I just have to correct Olaf's post:

    LINENO() used in ON ERROR requires debug info otherwise it returns 0. VFP interpreter cannot know the line number of code when an error occurs if the debug info is missing.

    LINENO() in a standard code does not require debug info and it is handled as a numeric constant during the compilation.

    Please test it again :-)

    • Marked as answer by eCasper Wednesday, January 16, 2013 5:34 AM
    Tuesday, January 15, 2013 10:06 PM
    Moderator
  • Pavel: I really did compile an exe without debug info using LINENO() and the correct line number is displayed, simply try yourself, compile this to an EXE:

    Messagebox(LineNo())

    Bye, Olaf.

    PS: My testcode was even more complex (to have at least two stack levels):

    myfunc1()

    Function myfunc1()
       AStackInfo(laStack)
       lnLineno = Lineno()
       Save to d:\sandbox\astackinfo\stack.mem
    EndFunc   

    I compiled this with and without debug info, with and without encryption and then inspected variables via RESTORE FROM. It turns out ASTACKINFO needs the debug info even just for the line number, encryption has no infulence, but that was what I expected anyway. LINENO() works always, that may be astonishing, but it is that way.

    • Edited by Olaf Doschke Wednesday, January 16, 2013 3:05 PM
    Wednesday, January 16, 2013 2:54 PM
  • Hi Olaf,

    What Pavel says is LINENO() *inside of an ON ERROR procedure would require debug info - if you put the following into the "main.PRG" of a test.PJX, you'd get a MessageBox(3) when you run the resulting test.EXE that has Debug Info, and MessageBox(0) if it has not.

    Regards
    -Stefan

    ON SHUTDOWN quit
    ON ERROR ErrorHandler(ERROR(), PROGRAM(), LINENO(), MESSAGE())
    ERROR 3
    
    READ EVENTS
    
    RETURN
    
    PROCEDURE ErrorHandler(tnError, tcProgram, tnLineNo, tcMessage)
    	MESSAGEBOX(m.tnLineNo)
    ENDPROC
    


    Wednesday, January 16, 2013 3:18 PM
  • OK, I see. Yes, it really get's 0 without debug info in that case. Why does the LINENO() result differ, when the actual exception is executed. This is very odd.

    Bye, Olaf.

    Wednesday, January 16, 2013 6:14 PM