Discussions related to Visual Prolog
David Snook
Active Member
Posts: 36
Joined: 6 Feb 2003 0:01

openfile issue

Unread post by David Snook »

I have another issue which seems to be related to VP 7.5 (I notice in the dump message "definiteUserError = true" and I suspect there may be something simple here). The code where the error occurs is as follows:

Code: Select all

  displayPrint(WIN,PAGE) =Y:-         retractFactDb(preview_update),         try inStream := inputStream_file::openFile8(re_temp_file_name)         catch TraceId do             STR = exceptionDump::dumpToString(TraceId), vpiCommonDialogs::note(STR), %temp line             Error = exception::getLastError(),             re_temp_open_er(WIN,convert(integer,Error)),fail         end try,         re_update_buffer(PAGE),         inStream:close()
The error dump message is displayed in the attachment. This is part of a rather large file and it runs fine in VP 7.4. I copied a backup and recompiled the program in VP 7.5 to see what changes may have occurred but there were only a few changes re:findall and replacing the TRAP predicate with TRY...CATCH routines.

The file that is trying to be opened is a temporary working file to print data from vpiTableed in a wysiwyg format. I can't figure out why it can't seem to create or open the file. "Error = exception::getLastError()" actually states that the "operation completed successfully" so I added the "STR = exceptionDump::dumpToString(TraceId), vpiCommonDialogs::note(STR)" line to see what was going on.

Any help would be greatly appreciated.

Cheers,

David Snook
Attachments
dump.jpg
dump.jpg (71.24 KiB) Viewed 22696 times
Harrison Pratt
VIP Member
Posts: 439
Joined: 5 Nov 2000 0:01

Unread post by Harrison Pratt »

I have an application in VIP 5.2 that uses a temporary file and it required a "wait until the file appears" loop to avoid "file not found" errors. Apparently the code would complete quickly, but the directory information was not updated before my application tried to read that file.

If you can see that the file in question eventually appears in the expected location, then you may have a timing issue.
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls »

The easy thing first, getLastError must be called immediately after the relevant operation. Calling dumping an exception state to a string and showing a dialog will surely invoke routines that sets new "last error" values.

Anyway, the error message (quite clearly) states that the file cannot be found; does it exist?

It appears that the name should be C:\Director\Exe\rep$$$.tmp
Regards Thomas Linder Puls
PDC
David Snook
Active Member
Posts: 36
Joined: 6 Feb 2003 0:01

Unread post by David Snook »

Hi Harrison,

I remember when I upgraded this particular module from VP 5.2 to VP 7 there was a timing issue as you suggested although I didn't think there would be any significant performance/timing issues between VP 7.4 and VP 7.5 (and it works in 7.4). I've tried some simple timing changes and so far no result although I have a feeling you may be right so will follow it through.

Thanks for the feedback.

Regards,

David
David Snook
Active Member
Posts: 36
Joined: 6 Feb 2003 0:01

Unread post by David Snook »

Hi Thomas,

It turns out there is a change in either the "try...catch" predicate or in the "exception" predicates.
In VP 7.4 the openfile routine causes an exception since the file has not yet been created. It's caught by the "try...catch" and getLastError produces error code 2 (file not found) and handled by the error handler re_temp_open_er. In VP 7.5 the getLastError returns error code 0 (Operation Completed Successfully) even though an exception is raised. The exceptionDump (third clause version) is the only predicate that returns the correct error code 2. If I try to use Error = exception::getErrorCode(TraceId) to get the error code from the TraceId it also produces error code 0 (second version of clause) even though an exception is raised.

I'm not sure now how to obtain the correct error code from the "try...catch" routine?

Let me know if my explanation makes sense?

Kind regards,

David

These first 2 clause versions both produce error code 0 even though an exception is raised

Code: Select all

  displayPrint(WIN,PAGE) =Y:-         retractFactDb(preview_update),         try inStream := inputStream_file::openFile8(re_temp_file_name)         catch TraceId do                Error = exception::getLastError(),                re_temp_open_er(WIN,convert(integer,Error)),fail         end try,

Code: Select all

  displayPrint(WIN,PAGE) =Y:-         retractFactDb(preview_update),         try inStream := inputStream_file::openFile8(re_temp_file_name)         catch TraceId do                Error = exception::getErrorCode(TraceId),                re_temp_open_er(WIN,convert(integer,Error)),fail         end try,
% The exceptionDump shows the correct error code and description

Code: Select all

  displayPrint(WIN,PAGE) =Y:-         retractFactDb(preview_update),         try inStream := inputStream_file::openFile8(re_temp_file_name)         catch TraceId do                  STR = exceptionDump::dumpToString(TraceId), vpiCommonDialogs::note(STR),
David Snook
Active Member
Posts: 36
Joined: 6 Feb 2003 0:01

Unread post by David Snook »

It came to mind that I could test the above by simply sending error code 2 (file not found) to the error handler in the event an exception is raised as in the following:

Code: Select all

  displayPrint(WIN,PAGE) =Y:-         retractFactDb(preview_update),         try inStream := inputStream_file::openFile8(re_temp_file_name)         catch _TraceId do                Error = 2                re_temp_open_er(WIN,convert(integer,Error)),fail         end try,
With the change above the print function completes as it should but the logic of the error handler is lost as there are other error codes that would otherwise be handled. When the getLastError predicate returned error code 0 (instead of 2) this was passed to the error handler and since it's not expected to handle a successful operation an exception was raised (within the logic of this module).

Hope that makes sense.

David
David Snook
Active Member
Posts: 36
Joined: 6 Feb 2003 0:01

Unread post by David Snook »

I created a small example project which demonstrates the problem.

Best wishes for the New Year!

Cheers,

David
Attachments
errortest.zip
(18.63 KiB) Downloaded 381 times
David Snook
Active Member
Posts: 36
Joined: 6 Feb 2003 0:01

Unread post by David Snook »

My description of the problem was somewhat indirect here but the exception routines to get the error code in the "try...catch" routine does not return the correct error at least with the "openfile" function.

I apologise if the issue is being looked at but as there was no response I thought this post might have been missed over the holiday period.

Kind regards,

David Snook
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls »

I must have missed all your mail the 31. Dec. But with the new post I have seen them.

getLastError returns the "last" error as indicated by the name. So to get the correct value it is crucial that it is called after the interesting function but before any other system function is called. Since any memory allocation can trigger a system call, getLastError must be called immediately after the call to the API function. It is "pure luck" that it worked in 7.4.

But in any case the correct way to deal with exceptions is described in the Exception Handling tutorial. Your problem is described in the Catching and handling exceptions section. The example actually looks very much like your problem.
Regards Thomas Linder Puls
PDC
David Snook
Active Member
Posts: 36
Joined: 6 Feb 2003 0:01

Unread post by David Snook »

Hi Thomas,

Thank you but I'm getting quite confused.

As far as I can tell the following will catch any and all reasons a file cannot be created or opened

Code: Select all

if D = exception::tryGetDescriptor(TraceId, fileSystem_api::cannotCreate) then...
What I need to do is determine whether the file does not yet exist (winErrors::error_file_not_found) or is the file already open (winErrors::error_sharing_violation Attempt to open an already opened file). My program response is different depending on which of these events occur.

Unless I'm missing something both situations above fall into "fileSystem_api::cannotCreate". Since "getLastError and "getErrorCode" won't work here is there a way to distinguish between the 2 events?

Regards,

David
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls »

It you look at your dump you will see that the error code is included in the information (together with the same value in HEX and the operating system description).

In the example you will see how the error description is fetched:

Code: Select all

if string(Description) = exception::tryGetExtraInfo(D, exception::errorDescription_parameter) then     stdio::writef("; %", Description) end if
The similar code for fetching the ErrorCode is:

Code: Select all

if unsigned(ErrorCode) = exception::tryGetExtraInfo(D, exception::errorCode_parameter) then     ... end if
You can combine the entire test like this:

Code: Select all

if unsigned(winErrors::error_file_not_found) = exception::tryGetExtraInfo(exception::tryGetDescriptor(TraceId, fileSystem_api::cannotCreate), exception::errorCode_parameter) then     ... end if
Or if you think that is too "compacted" you can expand it like this:

Code: Select all

if D = exception::tryGetDescriptor(TraceId, fileSystem_api::cannotCreate),     unsigned(ErrorCode) = exception::tryGetExtraInfo(D, exception::errorCode_parameter),     winErrors::error_file_not_found = ErrorCode then     ... end if
Regards Thomas Linder Puls
PDC
David Snook
Active Member
Posts: 36
Joined: 6 Feb 2003 0:01

Unread post by David Snook »

Ah now I get it! :idea:

I didn't read the description carefully and wasn't looking at the parameter in

Code: Select all

exception::tryGetExtraInfo
Thank you Thomas.
Post Reply