VBA-tools / VBA-Web

VBA-Web: Connect VBA, Excel, Access, and Office for Windows and Mac to web services and the web
http://vba-tools.github.io/VBA-Web/
MIT License
2.01k stars 494 forks source link

WebAsyncWrapper doesn't handle timeouts properly #374

Closed JackPai100 closed 5 years ago

JackPai100 commented 5 years ago

Hi Tim, Thank you for the project, it is very useful. I've used it to do sync web request, and it works perfectly. Now, I'm trying to make the request async, using WebAsyncWrapper. But I get Run-time error '13': Type mismatch when I call ExecuteAsync with a webrequest and string of the callback function.

I debug into the code, and the error happens at: web_StartTimeoutTimer() Application.OnTime Now + TimeValue("00:00:" & web_TimeoutS), "'WebHelpers.OnTimeoutTimerExpired """ & Me.Request.Id & """'"

So the OnTime registration failed. Of course, my callback won't be called.

I searched in the examples included in the package, but no examples for WebAsyncWrapper. Can you please share a working example for Excel 2010 or 2013?

Thanks Jack

P.S. here is my code snippet. Public Sub ProcessDataCB(Rsp As WebResponse) Dim Result As String Result = Rsp.Content Dim resDict As Dictionary Set resDict = ParseJson(Result) PrintDictionaryRange resDict, Worksheets("Bullet Bond Anywhere").Range("D8:D30") End Sub

Public Sub PostMessageAsync(Url As String, Message As String, Token As String) Dim IASClient As New WebClient Dim IASWrapper As New WebAsyncWrapper Set IASWrapper.Client = IASClient

IASClient.BaseUrl = Url
IASClient.TimeoutMs = 60000

Dim IASRequest As New WebRequest
IASRequest.Method = WebMethod.HttpPost

IASRequest.AddHeader "Authorization", "Bearer " + Token
IASRequest.RequestFormat = WebFormat.FormUrlEncoded
If Token = "" Then
    IASRequest.ResponseFormat = WebFormat.PlainText
Else
    IASRequest.ResponseFormat = WebFormat.Json
End If

IASRequest.Body = Message

' Execute the request and work with the response
IASWrapper.ExecuteAsync IASRequest, "Module1.ProcessDataCB"

End Sub

zgrose commented 5 years ago

You can probably workaround the issue by setting your timeout to 59 seconds (or anything under 60).

@timhall TimeValue is expecting a string representing a time. 08:08:30 is 8:08 AM and 30 seconds. Values >= 60 will fail to parse as type mismatch.

If you want to allow timeouts over 60 seconds you may have to use DateAdd("s", web_TimeoutS, Now) and then do some parsing to convert 11/27/2018 8:12:38 AM to 8:12:38 AM which OnTime expects instead.

JackPai100 commented 5 years ago

Thank you zgrose! You saved me from many hours of frustration! The issue was with the Client.TimeoutMs I set. I set it to 60 seconds, which the TimeValue had a problem to parse.

Thanks a lot!

lolo58200 commented 5 years ago

you can also convert your timeout in day fraction

Dim web_TimeoutInDayFraction As Double web_TimeoutInDayFraction = CDbl(web_TimeoutS) / 86400# ' 86400 = nb second per day Application.OnTime Now + web_TimeoutInDayFraction), ....

it works fine as long as you do not call Application.OnTime from a class module otherwise you will hit https://github.com/VBA-tools/VBA-Web/issues/373

timhall commented 5 years ago

@zgrose Thanks for the pointer for DateAdd

jemferraz commented 2 years ago

@timhall Sorry to bother, but I have run into an analogous problem: I am using the library VBA-Web to request some heavy calculations, that might take more than 10 min to run. I've tried both synchronous as well as asynchronous requests, by setting client.TimeoutMs to 600000 (10min), but after 60s, the response (or callback) returns, while the API is still processing... I've read somewhere else (https://github.com/VBA-tools/VBA-Web/issues/389) that there might be a problem with office 64bits. Do you have any idea or suggestion? Thanks

zgrose commented 2 years ago

You probably should re-implement that API, if possible, to be a fire and forget then poll for completion. POST /my-long-operation receive job ID (or supply one) and then GET /job-status?id=foo

Just my 0.02 if you have control over the endpoint.

jemferraz commented 2 years ago

@zgrose Thanks for the tip. I'll see what can be done...