'File not found' error on an existing file - asp-classic

I have sometimes a 'file not found' error on the 'DeleteFile' line of this small script:
(I guess when several clients open the script as the same time)
if objFSO.FileExists(fileName) then
Set f = objFSO.GetFile(fileName)
if DateDiff("d", f.DateLastModified, date()) > 3 then
Application.Lock
objFSO.DeleteFile(fileName)
Application.Unlock
end if
Set f = nothing
end if
But this should be protected by the 'FileExists' on the first line?
Any idea ? Thanks.

You're running into a race condition. The file attributes are cached in the second line with GetFile. If the file exists at that point, the code will continue to run. You either need to lock before that point, or refresh your attribute cache and double-check existence after Application.Lock.

Related

Lua script failed clicking on a button

I'm trying to scrape flights from link with scrapy-splash using this lua script:
function main(splash)
local waiting_time = 2
-- Go to the URL
assert(splash:go(splash.args.url))
splash:wait(waiting_time)
-- Click on "Outgoing tab"
local outgoing_tab = splash:select('#linkRealTimeOutgoing')
outgoing_tab:mouse_click()
splash:wait(waiting_time)
-- Click on "More Flights" button
local more_flights_btn = splash:select('#ctl00_rptOutgoingFlights_ctl26_divPaging > div.advanced.noTop > a')
more_flights_btn:mouse_click()
splash:wait(waiting_time)
return splash:html()
end
and from some reason I'm getting this error:
'LUA_ERROR', 'message': 'Lua error: [string "..."]:16: attempt to index local \'more_flights_btn\' (a nil value)', 'error': "attempt to index local 'more_flights_btn' (a nil value)"}, 'type': 'ScriptError', 'description': 'Error happened while executing Lua script'}
Does anyone know why this happens?
Also does anyone know where I can get a toturial for lua script integration with splash? besides the offical site?
Thanks in advance!
This just looks like a timing issue. I ran your Lua script a couple of times and I got that error only once.
Simply waiting longer before getting the button should be enough. However, if the time it takes varies a lot and you don't always want to wait the full time, then you can try a slightly smarter loop like this:
-- Click on "More Flights" button
local more_flights_btn
-- Wait up to 10 seconds:
for i=1,10 do
splash:wait(1)
more_flights_btn = splash:select('#ctl00_rptOutgoingFlights_ctl26_divPaging > div.advanced.noTop > a')
if more_flights_btn then break end
-- If it was not found we'll wait again.
end

applescript - quicktime 7 audio (wav) export

I'm working on a script to help my workflow. My work involves sound design, and I often have to take videos and extract the audio. Regardless of the source/compression, I like it in .wav format - best quality, accepted by all audio editing software, and least overhead for playback in a live environment.
Currently, I use Quicktime Pro 7's Export feature for this task - the current Quicktime X doesn't export to .wav. Built into the OS, so instead of using a separate tool, I'm using QT.
I am using Automator to write a service - select the file, open it in QT, export as wav and save it in the same location as the original, then quit. Here is what I have so far, and I keep getting an error. "The action “Run AppleScript” encountered an error." It compiles properly, but nothing comes out. Late last night I got it to spit out .mov files for some reason (despite trying to tell it wave) and now I can't even get back there.
Any help is appreciated. As you can see from the commented parts, I was trying to specify anywhere, since trying to make it the same location as the original was escaping me. Currently I'm just having it prompt me on where to save, so I can just tackle one problem at a time. Cheers!
tell application "QuickTime Player 7"
--set saveFile to POSIX path of (((path to desktop) as Wave) & "test.wav")
set outfile to choose file name with prompt "Save altered file here:"
set error_states to {load state unknown, load error}
set successful_states to {loaded, complete}
repeat until load state of first document is in (error_states & successful_states)
delay 0.1
end repeat
tell document to save in outfile
if (load state of first document is in successful_states) then
if (can export first document as wave) then
export first document to outfile as wave
else
error "Cannot export " & (source_file as string) & " in .wav (Wave) format."
end if
else
error "File is not in a successful load state: " & (load state of first document as string)
end if
end tell
The file output should have '.wav" extension. To do so, I changed a bit your script and I remove the "tell document to save in outfile".
if you really want to delete your initial file after export, you need to add that at end of the script (I prefer to check the export is successful before deletion !).
Also, you must change the first line to replace the choose file (for my tests) to the read input variable from Automator service script :
set InFile to choose file "select video file for test only" -- to be replace by the input of your Automator Service
-- conversion of selected file with proper folder and new '.wav" extension
tell application "Finder"
set FFolder to (container of InFile) as string
set FName to name of InFile
set FExt to name extension of InFile
end tell
set Pos to offset of FExt in FName
if Pos > 0 then --change extension from current to 'wav'
set OutFile to FFolder & (text 1 thru (Pos - 1) of FName) & "wav"
else
set OutFile to FFolder & FName & ".wav"
end if
tell application "QuickTime Player 7"
activate
open InFile
set error_states to {load state unknown, load error}
set successful_states to {loaded, complete}
repeat until load state of first document is in (error_states & successful_states)
delay 0.1
end repeat
if (load state of first document is in successful_states) then
if (can export first document as wave) then
export first document to OutFile as wave
else
error "Cannot export " & (source_file as string) & " in .wav (Wave) format."
end if
else
error "File is not in a successful load state: " & (load state of first document as string)
end if
end tell

Too many exceptions causes error 5635? (An actual Stack Overflow!)

I've got a problem with ABL exception handling. If looks as if raising too many exceptions gets you an error 5635? Which would make exception trapping not entirely useful, if true.
Has anyone else seen this?
Does anyone know of a way around it, short of going back to old-style ABL code without exception handling?
Here is (some of) my actual code. Lots of weird external calls but it's the exception checking we are talking about here:
for each b-archead
where b-archead.depot = ip-depot
and b-archead.o-week >= ip-startwk
and b-archead.o-week <= ip-endwk
use-index o-week
no-lock
on error undo, throw:
assign v-directory = b-archead.directory
v-invoice = b-archead.invoice
v-o-date = b-archead.o-date
v-path = arc_path(buffer b-archead)
v-success = no
v-error = "".
if not file_status(v-path) begins "Y"
then
undo, throw new progress.lang.apperror
(subst("Source file '&1' missing", v-path), 300).
run process_one (buffer b-archead, input v-path, input ip-todir).
v-success = yes.
catch e2 as progress.lang.error:
v-error = e2:getmessage(1).
run log ( 'w', v-error ).
next.
end catch.
finally:
put stream s-out unformatted
csv_char(v-directory)
',' csv_int(v-invoice)
',' csv_date(v-o-date)
',' csv_int(v-o-week)
',' csv_char(v-path)
',' csv_char(v-success)
',' csv_char(v-error)
skip.
end finally.
end.
Here is the error I get when I run it and most of the archead records result in an exception:
SYSTEM ERROR: -s exceeded. Raising STOP condition and attempting to write stack
trace to file 'procore'. Consider increasing -s startup parameter. (5635)
The code works fine with one or two exceptions; it only fails when there are a lot of them (hundreds?) -s is set to 150, which seems okay to me.
-s error can occur when you have an infinitive loop.
for example:
run a.
procedure a:
run b.
end.
procedure b:
run a.
end.
It could be a problem in file_status function, process_one or log procedure.
Regrettably -- and until I can get a more definitive answer -- it does in fact appear that there is an upper limit on the number of exceptions you can catch.
Here is the shortest code that reproduces the problem:
def var v-i as int no-undo.
do v-i = 1 to 5000 on error undo, throw:
undo, throw new progress.lang.apperror ( "error message" ).
catch e as progress.lang.apperror:
message "boo". pause 0.
end catch.
end.
For me this always falls over with the error above at the point when v-i = 4583. If my exception uses an error number, i.e. undo, throw new progress.lang.apperror ("error message", 1234)., then the number is 2293.
The lack of complexity of the failing code, plus the fact that the number of iterations you get depends on the complexity of the error object, leads me to believe that it is the error object that is causing the overflow. In other words, e is not cleared down with each iteration.
Whether or not this is a bug in my Openedge (10.2B) it's certainly something I will have to work around in future.
EDIT: the workaround turns out to be painfully obvious once you know it. The error object is scoped to the enclosing block, so don't use catch against a block if it iterates:
def var v-i as int no-undo.
do v-i = 1 to 5000 on error undo, throw:
do on error undo, throw:
undo, throw new progress.lang.apperror ( "error message" ).
catch e as progress.lang.apperror:
message "boo". pause 0.
end catch.
end.
end.
Log the activity to see what is actually going on - check the LOG-MANAGER docs for more info.

PROGRESS - Validating a user-input file output path

I've written some PROGRESS code that outputs some data to a user defined file. The data itself isn't important, the output process works fine. It's basically
DEFINE VARIABLE filePath.
UPDATE filePath /*User types in something like C:\UserAccount\New.txt */
OUTPUT TO (VALUE) filePath.
Which works fine, a txt file is created in the input directory. My question is:
Does progress have any functionality that would allow me to check if an input
file path is valid? (Specifically, if the user has input a valid directory, and if they have permission to create a file in the directory they've chosen)
Any input or feedback would be appreciated.
FILE-INFO
Using the system handle FILE-INFO gives you a lot of information. It also works on directories.
FILE-INFO:FILE-NAME = "c:\temp\test.p".
DISPLAY
FILE-INFO:FILE-NAME
FILE-INFO:FILE-CREATE-DATE
FILE-INFO:FILE-MOD-DATE
FILE-INFO:FILE-INFO
FILE-INFO:FILE-MOD-TIME
FILE-INFO:FILE-SIZE
FILE-NAME:FILE-TYPE
FILE-INFO:FULL-PATHNAME
WITH FRAME f1 1 COLUMN SIDE-LABELS.
A simple check for existing directory with write rights could be something like:
FUNCTION dirOK RETURNS LOGICAL (INPUT pcDir AS CHARACTER):
FILE-INFO:FILE-NAME = pcDir.
IF INDEX(FILE-INFO:FILE-TYPE, "D") > 0
AND INDEX(FILE-INFO:FILE-TYPE, "W") > 0 THEN
RETURN TRUE.
ELSE
RETURN FALSE.
END FUNCTION.
FILE-NAME:FILE-TYPE will start with a D for directories and a F for plain files. It also includes information about reading and writing rights. Check the help for more info. If the file doesn't exist basically all attributes except FILE-NAME will be empty or unknown (?).
Edit: it seems that FILE-TYPE returns W in some cases even if there's no actual writing rights in that directory so I you might need to handle this through error processing instead
ERROR PROCESSING
OUTPUT TO VALUE("f:\personal\test.txt").
PUT UNFORMATTED "Test" SKIP.
OUTPUT CLOSE.
CATCH eAnyError AS Progress.Lang.ERROR:
/* Here you could check for specifically error no 98 indicating a problem opening the file */
MESSAGE
"Error message and number retrieved from error object..."
eAnyError:GetMessage(1)
eAnyError:GetMessageNum(1) VIEW-AS ALERT-BOX BUTTONS OK.
END CATCH.
FINALLY:
END FINALLY.
SEARCH
When checking for a single file the SEARCH command will work. If the file exists it returns the complete path. It does however not work on directory, only files. If you SEARCH without complete path e g SEARCH("test.p") the command will search through the directories set in the PROPATH environment variable and return the first matching entry with complete path. If there's no match it will return unknown value (?).
Syntax:
IF SEARCH("c:\temp\test.p") = ? THEN
MESSAGE "No such file" VIEW-AS ALERT-BOX ERROR.
ELSE
MESSAGE "OK" VIEW-AS ALERT-BOX INFORMATION.
SYSTEM-DIALOG GET-FILE character-field has an option MUST-EXIST if you want to use a dailogue to get filename/dir from user. Example from manual
DEFINE VARIABLE procname AS CHARACTER NO-UNDO.
DEFINE VARIABLE OKpressed AS LOGICAL INITIAL TRUE.
Main:
REPEAT:
SYSTEM-DIALOG GET-FILE procname
TITLE "Choose Procedure to Run ..."
FILTERS "Source Files (*.p)" "*.p",
"R-code Files (*.r)" "*.r"
MUST-EXIST
USE-FILENAME
UPDATE OKpressed.
IF OKpressed = TRUE THEN
RUN VALUE(procname).
ELSE
LEAVE Main.
END.

Vendors black box function can only be called successfully once

(first question here, sorry if I am breaking a piece of etiquette)
My site is running on an eCommerce back end provider that I subscribe to. They have everything in classic ASP. They have a black box function called import_products that I use to import a given text file into my site's database.
The problem is that if I call the function more than once, something breaks. Here is my example code:
for blah = 1 to 20
thisfilename = "fullcatalog_" & blah & ".csv"
Response.Write thisfilename & "<br>"
Response.Flush
Call Import_Products(3,thisfilename,1)
Next
Response.End
The first execution of the Import_Products function works fine. The second time I get:
Microsoft VBScript runtime error '800a0009'
Subscript out of range: 'i'
The filenames all exist. That part is fine. There are no bugs in my calling code. I have tried checking the value of "i" before each execution. The first time the value is blank, and before the second execution the value is "2". So I tried setting it to null during each loop iteration, but that didn't change the results at all.
I assume that the function is setting a variable or opening a connection during its execution, but not cleaning it up, and then not expecting it to already be set the second time. Is there any way to find out what this would be? Or somehow reset the condition back to nothing so that the function will be 'fresh'?
The function is in an unreadable include file so I can't see the code. Obviously a better solution would be to go with the company support, and I have a ticket it in with them, but it is like pulling teeth to get them to even acknowledge that there is a problem. Let alone solve it.
Thanks!
EDIT: Here is a further simplified example of calling the function. The first call works. The second call fails with the same error as above.
thisfilename = "fullcatalog_testfile.csv"
Call Import_Products(3,thisfilename,1)
Call Import_Products(3,thisfilename,1)
Response.End
The likely cause of the error are the two numeric parameters for the Import_Products subroutine.
Import_Products(???, FileName, ???)
The values are 3 and 1 in your example but you never explain what they do or what they are documented to do.
EDIT Since correcting the vender subroutine is impossible, but it always works for the first time it's called lets use an HTTP REDIRECT instead of a FOR LOOP so that it technically only gets called once per page execution.
www.mysite.tld/import.asp?current=1&end=20
curr = CInt(Request.QueryString("current"))
end = CInt(Request.QueryString("end"))
If curr <= end Then
thisfilename = "fullcatalog_" & curr & ".csv"
Call Import_Products(3,thisfilename,1)
Response.Redirect("www.mysite.tld/import.asp?current=" & (curr + 1) & "&end=" & end)
End If
note the above was written inside my browser and is untested so syntax errors may exist.

Resources