libURL gone mad
Richard Gaskin
ambassador at fourthworld.com
Sat Sep 3 10:43:45 EDT 2016
Charles Warwick wrote:
> If I understand correctly what you are after, how about just arbitrating
> the network requests yourself and then the issue would go away entirely.
So I had thought. But "GET" and "POST" are handled in an unusual way in
LC: they're kinda synchronous, and kinda not, behaving in a
semi-quasi-threaded way that sometimes makes it difficult to know how to
work with them.
For example, I like to use functions for things that access data from
the Internet. As sources of value they fit well with how my code flows.
I often like being able to handle libURL errors returned in "the result"
generically within the function, leaving any server-side errors returned
from my CGI to the routine that calls the function.
To handle errors generically within the function, I sometimes show an
answer dialog, and then "exit to top" - here's a simplified example:
on mouseUp
put cgiRequest("http://something/on/a/server") into tDataFromServer
if word 1 of tDataFromServer is "error" then
-- provide some meaningful feedback based on what the
-- the server is telling us
else
put tDataFromServer into fld "ShowMeWhatsOnTheServer"
end if
end mouseUp
function cgiRequest pURL
get url pURL
put the result into tRequestError
put it into tDataReturnedFromServer
--
-- Check errors reported by libURL:
if tRequestError is not empty then
answer "Whoops! Something went wrong: "& tRequestError
exit to top ---< NOTE THIS - we'll discuss it below
end if
--
-- No errors reported, presumably good data:
return tDataReturnedFromServer
end cgiRequest
With your libURL mod you posted the other day, we can extend that to
exclude requests being syncblocked as well:
function cgiRequest pURL
if libUrlIsSyncBlocked() is true then
answer "Slow down, I'm still working"
exit to top --< NOTE THIS - see below
end if
--
get url pURL
put the result into tRequestError
put it into tDataReturnedFromServer
--
-- Check errors reported by libURL:
if tRequestError is not empty then
answer "Whoops! Something went wrong: "& tRequestError
exit to top ---< NOTE THIS - we'll discuss it below
end if
--
-- No errors reported, presumably good data:
return tDataReturnedFromServer
end cgiRequest
In terms of the non-threaded LiveCode we know and love, the above would
seem logically sound. Indeed, I use functions, with "exit to top" as
part of error handling, to access all sorts of values stored in files,
fields, properties, etc. without issue, allowing me to centralize
generic error handling while still providing super-simple syntax in my
libraries for the UI elements that call it.
But in practice, I've found that if I call "exit to top" within a second
call to a handler that calls libURL, the previous call to libURL never
completes, and any subsequent calls have no effect.
Even more interestingly, in the second version of the cgiRequest
function above, "exit to top" can be called before anything in libURL is
called (if the syncblock is encountered), yet somehow the current libURL
execution stack from the previous call to that function is still affected.
At some point I can give up and call libUrlResetAll and start over, but
it's difficult to know in code exactly when I should give up, and I
really don't like calling libUrlResetAll if I can avoid it since it's a
fairly deep reset best avoided unless absolutely necessary.
I can use "exit to top" as part of error handling within functions
safely in just about every other context.
But if used in any handler that calls libURL, it seems to throw off
previous calls that use libURL, in ways I haven't been able to wrap my
head around.
It would be possible to rewrite my cgiRequest function as a command, but
stylistically it's less desirable, and materially it would mean
rewriting everything in the code base that calls it.
If absolutely necessary, then of course I'd have no choice. It's
nothing a cup of coffee and a few hours can't fix. :)
But I'm hoping there's some way to better understand LC's
semi-quasi-threaded behavior with "GET" and "POST" which would allow me
to handle errors within a function that accesses a server resource as
gracefully as I can when accessing just about anything else.
Any tips?
PS: In some cases in my testing I've been able to come up with a
sequence of calls in which running "GET" through libURL produces no
value in either "it" or "the result". This leaves me in the uniquely
disadvantageous state of having encountered some sort of error without
any means of knowing it. That one will take more time to pin down the
recipe for, but when I do I'll submit a report for it.
--
Richard Gaskin
Fourth World Systems
Software Design and Development for the Desktop, Mobile, and the Web
____________________________________________________________________
Ambassador at FourthWorld.com http://www.FourthWorld.com
More information about the use-livecode
mailing list