Best way to catch a HTTP Timeout from the ClientBuilder - Forum - OpenEdge Development - Progress Community

Best way to catch a HTTP Timeout from the ClientBuilder

 Forum

Best way to catch a HTTP Timeout from the ClientBuilder

This question is not answered

Hi Guys

I'm using the Clientbuilder for a while now. For speed I've set it up based on one of the examples online

Now I'm wondering, if I where to change the example below and insert a timeout

Example
oResponse = ClientBuilder:Build():Client:Execute(oRequest).

Would become
oResponse = ClientBuilder:Build():Client:SetRequestTimeout(10):Execute(oRequest).

What would be the best way to capture the timeout? 

Will the clientbuilder throw an error? Or will it return an error statuscode?

Couldn't find this in the documentation, so I thought I'd just ask before logging a supprt case.

REgards, Onno

-------- UPDATE EXAMPLE ------

BLOCK-LEVEL ON ERROR UNDO, THROW.

USING OpenEdge.Core.String.
USING OpenEdge.Net.HTTP.ClientBuilder.
USING OpenEdge.Net.HTTP.IHttpRequest.
USING OpenEdge.Net.HTTP.IHttpResponse.
USING OpenEdge.Net.HTTP.RequestBuilder.
USING Progress.Json.ObjectModel.JsonObject. 

DEFINE VARIABLE httpUrl AS CHARACTER NO-UNDO.
DEFINE VARIABLE oRequest AS IHttpRequest NO-UNDO.
DEFINE VARIABLE oResponse AS IHttpResponse NO-UNDO.
DEFINE VARIABLE oRequestBody AS String NO-UNDO.
DEFINE VARIABLE oJsonEntity AS JsonObject NO-UNDO.
DEFINE VARIABLE JsonString AS LONGCHAR NO-UNDO.

SESSION:DEBUG-ALERT = TRUE.
httpUrl = "www.googleapis.com/.../token".

oRequestBody = new String('client_id=your_client_id&client_secret=your_client_secret&refresh_token=your_refresh_token&grant_type=refresh_token').

oRequest = RequestBuilder:Post("www.googleapis.com/.../token", oRequestBody)
:ContentType('application/x-www-form-urlencoded')
:AcceptJson()
:Request.

oResponse = ClientBuilder:Build():Client:SetRequestTimeout(10):Execute(oRequest).

MESSAGE
oResponse:StatusCode SKIP
oResponse:StatusReason SKIP
VIEW-AS ALERT-BOX.

oJsonEntity = CAST(oResponse:Entity, JsonObject).
oJsonEntity:Write(JsonString, TRUE).

MESSAGE STRING(JsonString)
VIEW-AS ALERT-BOX.

All Replies
  • Hi guys

    Anyone any thoughts on this?

  • Are you able to create a timeout scenario and test your code?  Maybe you can just change the host name in the url to something that doesn't exist.

    I'm fairly certain you will catch an error from that code if anything goes wrong.  OO programming and SEH error handling work well together, and I'd guess that all these new API's would throw errors by convention.  It is much better for API's to follow a standard pattern than come up with their own strange and unique error -publication strategies (just thinking about ugly API's like OS-COPY give me a cold chill).

    Are you already familiar with structured error handling (SEH)?  If not I would highly recommend that you read the "Error Handling" document from beginning to end.

    community.progress.com/.../2911.openedge-11-7-product-documentation

    The most important parts in there are related to "Structured Error Handling".  This is a similar error-handling pattern to what is found in other languages like Java and C#.

    I suspect that if you put a do/catch block around all that code, you will probably be able to CATCH a Progress.Lang.Error (or more specifically a class that derives from it).   See. documentation.progress.com/.../index.html

    Have you tried that?  The OpenEdge.Net.HTTP stuff is open source so you can go look for yourself to see if there are lots of UNDO, THROW statements in the case of error conditions.  This will be your biggest clue.  Here is a link to another conversation about that API.  Peter Judge seems to be the expert, if not the author:

    community.progress.com/.../36251

  • Hey Onno,
     
    There HTTP library listens for timeouts and throws an error if one happens.  An OpenEdge.Net.HTTP.HttpRequestError is thrown (which is an AppError).
     
     
    The ClientSocket used by the HTTP library publishes a number of events; you could subscribe to them from the code that instantiates the HTTP client.
       
        /** Event fired when a chunk of data is received from the socket */
        define public event DataReceived signature void (input poSender as ClientSocket,
                                                         input poEventArgs as SocketReadEventArgs).
       
        /** Fired when a read times out (optional based on a timeout) */
        define public event ReadTimeout signature void (input poSender as ClientSocket,
                                                        input poEventArgs as SocketReadEventArgs).
       
        /** Fired when a read is terminated for an reason (socket disconnect, no data etc) */
        define public event ReadTerminated signature void (input poSender as ClientSocket,
                                                           input poEventArgs as SocketReadEventArgs).
       
     
    The code at github.com/.../set_options.p  shows how you can use a ClientSocket object of your choosing (from which you'd subscribe to the events).
     
    Note that if you go this route,
    - you have to be careful of holding on too long, and preventing GC of the socket
    - I'm not sure of the program flow, since an error is thrown (as opposed to added to the EventArgs object); I'd have a catch block in place.
     
    hth,
    -- peter