URLConnection Issues in Windows

Hello Team,

I am having an issue with URLConnection and Windows. It works on Mac. I am using the api for square to connect to a terminal.

When making this call from my custom Xojo app on a Mac machine, this call works. No rrrors. The same custom app running on windows 11 provides the error below which i do not understand because i am not including any idempotency_key field.

Below are my logs…

2024-05-08 17:27:27: Request Endpoint - https://connect.squareupsandbox.com/v2/devices/codes/X402DC55SD90
2024-05-08 17:27:27: Request Response - {"errors": [{"code": "BAD_REQUEST","detail": "The field named 'idempotency_key' is unrecognized (line 1, character 2)","field": "idempotency_key","category": "INVALID_REQUEST_ERROR"}]}

This happens when making a call to the api GetDeviceCode or api GetTerminalCheckout on windows. It looks like the first call to CreateDeviceCode and CreateTerminalCheckout work fine. Maybe since those previous calls are done first everything works but then the second calls fail with the error above because…?

The sub below fails when calling it second, but it seems to work if i call it first.

Sub GetDeviceCode(deviceCodeId As String)
  'GetDeviceCode API Call
  'GET https://connect.squareupsandbox.com/v2/devices/codes/{DEVICE_CODE_ID}
  'Square-Version: 2024-04-17
  'Authorization: Bearer {TOKEN}
  'Content-Type: application/json
    
  Try
    Var url  As String = App.GetAPIURL() + "/v2/devices/codes/" + deviceCodeId
    
    Self.mDeviceCodeId = deviceCodeId
    
    Self.RequestHeader("Square-Version") = "2024-04-17"
    Self.RequestHeader("Authorization") = "Bearer " + Self.mAccessToken
    Self.RequestHeader("Content-Type") = "application/json"
    Self.Send("GET", url )
  Catch err as RuntimeException
    MessageBox("DeviceConnector CreateDeviceCode Error: " + err.Message)
  End
End Sub

This is the first call

Sub CreateDeviceCode(deviceName As String, idempotencyKey As String, locationId As String)
  'POST https://connect.squareupsandbox.com/v2/devices/codes //FOR TESTING
  'POST https://connect.squareup.com/v2/devices/codes // FOR PROD
  'Square-Version: 2024-04-17
  'Authorization: Bearer {TOKEN}
  'Content-Type: application/json
  '
  '{
  '    "idempotency_key": "0a86b4e1-1b29-4332-98c6-4703c1afe33e",
  '    "device_code": {
  '        "name": "MyApp",
  '        "product_type": "TERMINAL_API",
  '        "location_id": "LOCATION_HERE"
  '    }
  '}
    
  Try
    Var url  As String = App.GetAPIURL() + "/v2/devices/codes"
    Var body As New JSONItem
    Var deviceCode As New JSONItem
    
    deviceCode.value("name") = deviceName
    deviceCode.value("product_type") = "TERMINAL_API"
    
    If Not locationId.IsEmpty Then
      deviceCode.value("location_id") = locationId //Square will use the default location
    End If
    
    body.value("idempotency_key") =  idempotencyKey
    body.value("device_code") = deviceCode
    
    Self.RequestHeader("Square-Version") = "2024-04-17"
    Self.RequestHeader("Authorization") = "Bearer " + Self.mAccessToken
    Self.RequestHeader("Content-Type") = "application/json"
    Self.SetRequestContent(body.ToString, "application/json")
    Self.Send("POST", url)
  Catch err as RuntimeException
    MessageBox("DeviceConnector CreateDeviceCode Error: " + err.Message)
  End
End Sub

To me as you can see the idempotency_key is added to the first call CreateDeviceCode in the body not header and because of this somehow the second call GetDeviceCode fails. Sticky headers or something weird happening or something is added to the second call were it does not need to be there. Again this works on the mac with no issues. Any guidance will be great.

TIA

This doesn’t look like sticky headers, but a sticky body. The GET request works when it comes first because no body is set yet. It fails when it comes second because the previous body is being sent. Try explicitly setting the body to empty for GET requests, or creating a new URLConnection for each request.

1 Like

I always create a new urlconnection for each request so I start clean each time.

3 Likes

I just did a simple hack…

Self.SetRequestContent("", "application/json") //this will stop issues in MS Windows with sticky body

I wanted to instanciate a different URLConnection everytime i had a call. But i was wondering how would i do the contentreceived event. Maybe with an addhandler (delegate)? Not sure. Thank you for your insights!

You can subclass the urlconnection & implement the data received event handler.

That’s not a hack, that’s the proper way of reusing the object changing the body of the request (in this case, to nothing).

1 Like