lotus-noteslotus-dominolotusscripthcl-notes

Runtime Error 53 "File Not Found" from LotusScript agent (SOLVED)


For unknown reasons a server-side LotusScript agent is throwing Error 53 "File not found" while trying to read the physical file size of an existing mail archive file. Situation is as follows:

the LS agent is looping all files in a given directory "\archive" right below the server's "\Data" dir. The Server in question is Domino 10.0.1 running on a Windows 2016 Server. The LS code is looping the directory looking for database files whose names follow a given pattern like "a_EmployeeID.nsf". If a DB's filename fits the pattern the code scans the server's names.nsf for the archive owner using the EmployeeID from the filename. If no person doc for that ID is found the code tries to read the db's physical file size using FileLen(filePath & FileName). Then the resulting data (filepath + file size) + EmployeeID are written to a report file on disk. Files that don't follow the pattern are also at least written back to the report. The idea behind that agent is to find "orphaned" or misplaced databases.

For ~80% of the files scanned this works fine, the records with exact file sizes are written to the report. But for the other ~20% runtime error 53 "File not found" pulls up. In those case the record just contains the file path/name + EmployeeID (if available) + "-1" for the file size. Because the file obviously do exist I assume that this is an access or security problem.

The agent is signed with an admin ID having maximum access rights on both the server and the archive files in question (the ID by policy has Manager access in the dbs' ACLs). The agent's security settings are set to level 3 (unrestricted access with full admin rights) because I first had signed the agent with an ID having Full Admin Access on the server (same result as with the now used ID).

Comparing the databases' ACLs I can't find any differences between those that "work" and the ones that don't. What I see, though, is that it's apparently always the same databases that are throwing this error, so this isn't a random problem.

For completeness here are the crucial parts of the agent code:

sFileName = Dir$(sPath & "*.nsf")
Do Until sFileName = ""
    iCount = iCount + 1
    sEmpid = "" 'reset
    lSizeArc = 0 'reset
    dblSizeArc = 0 'reset
    sSizeArcFmt = "" 'reset
    If(sFileName Like sPattern) Then
        sEmpid = Left(Right(sFileName, Len(sFileName) - 2), 6)
        Set vec = vwEgid.Getallentriesbykey(sEmpid, True)
        If(vec.count = 0) Then
            On Error 53 Resume Next 'Error 53 ("File not found")
            lSizeArc = FileLen(sPath & sFilename)
            If(Err = 53) Then
                lSizeArc = -1
                sSizeArcFmt = "-1 (no size available)"
                Err = 0
            Else
                dblSizeArc = Round((lSizeArc / 1024 / 1024), 3)
                sSizeArcFmt = Format$(dblSizeArc, "0.000") & " MB"
            End If
            Print #iFileNum,_
                "ORPHANED_ARCHIVE;" & sEmpid & ";" & sFileName & ";" & sSizeArcFmt
        End If
    Else
        On Error 53 Resume Next 'Error 53 ("File not found") 
        lSizeArc = FileLen(sPath & sFilename)
        If(Err = 53) Then
            lSizeArc = -1
            sSizeArcFmt = "-1 (no size available)"
            Err = 0
        Else
            dblSizeArc = Round((lSizeArc / 1024 / 1024), 3)
            sSizeArcFmt = Format$(dblSizeArc, "0.000") & " MB"
        End If
        Print #iFileNum,_
            "BAD_FILE_PATTERN;NO_EGID;" & sFilename & ";" & sSizeArcFmt
    End If
    sFileName = Dir$() 'next file
Loop 

Before I start moving in a different direction like looking into using Windows shell or .dll commands I'd really like to understand why in some cases the code insists that some of the files looked at cannot be "found".

Any ideas?

UPDATE 2021-05-19

So finally I found the solution to that weirdness (and it's not a compliment to my programming skills, I admit): looking again at the files that are throwing error 53 I realized that they all are rather big, > 2.1 GB to be exact. So I have to admit that I made a stupid programming error: assigning a value that size to a LONG variable won't work, of course. Stupid amateur error ... (But then why doesn't the code throw the proper error telling the value exceeds the limits, as it usually does?) Anyways, so I changed the variable to be a DOUBLE. But: result is still the same, though >> error 53. Then again looking at Designer help I found this small note:

FileLen returns a Long value

In other words: FileLen itself cannot handle files that size, and that error apparently is thrown before the interpreter finds out about my bad coding. In other words: no way to solve my problem that way. Back to @TorstenLink's comment: I'll use his method now

Extremely strange error message, still, I would say...

Thanks to everyone helping me think ;)


Solution

  • LotusScript is probably making a call to a 32 bit WinAPI to obtain the file-length and this call will be returning a unsigned 32 bit value, for a maximum file size of ~4.2Gb. However, LS doesn't support unsigned 32 bit values, only signed, so any value returned over 2.1Gb is represented by a negative value.

    You can take the absolute value of the negative value and put it in a currency or single/float, and add 2.1Gb to get a file-size up to 4.2Gb, but no bigger, since the API call won't be returning a bigger number and therefore, the API call probably doesn't consider this an error and LS hasn't technically 'overflowed' generating a size error.

    Alternatively, if you consider any size over say 1Gb as 'reportable' just look for values that are either +ve and > 1gb or < 0 as any negative value means 'big'. I'm guessing the exact file size isn't that important to you.