I was working on this Logic App that pulls results from a SharePoint list and outputs via HTTP. The Logic App is triggered via HTTP, in my case using Invoke-RestMethod
, and it outputs the results as a response.
This works fine as long as the results are returned in a minute+. If it takes more than 2 minutes Invoke-RestMethod
times out. This is even after you add a switch like -TimeoutSec 600
(for 10 mins). Ditto with Invoke-WebRequest
.
The solution is to use asynchronous requests with the Logic App. On the Logic App side it’s dead simple. You would usually have a Response block like this:
Click the 3 dots, go to Settings, and toggle it.
On the client/ PowerShell side while I might usually have had code like this:
1 |
$output = Invoke-RestMethod -Method POST -Uri $logicAppUrl -Headers $header -ContentType 'application/json' |
Now I need to change the behaviour a bit. On the initial HTTP trigger the call will succeed immediately; but the headers of the result will contain a location field header which has a URL I can keep polling while the status code is 202. This URL will have the results from the Logic App assuming it exits cleanly with a status code 200.
I can’t use Invoke-RestMethod
any more as that has no way of looking at the headers. So Invoke-WebRequest
it is. The code now becomes this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# Trigger the Logic App $output1 = Invoke-WebRequest -Method POST -Uri $logicAppUrl -Headers $header -ContentType 'application/json' -UseBasicParsing # Get the new URL from the Location Header # In PowerShell 7 this is an array. In PowerShell 5 it's a string. So I cast it to a string to be on the safe side. [string]$newUrl = $output1.Headers.Location # Keep polling the new URL at regular intervals as long as the status code is 202 do { $output2 = Invoke-WebRequest -Method GET -Uri $newUrl -Headers $header -ContentType 'application/json' -UseBasicParsing Start-Sleep -Seconds 5 } while ($output2.StatusCode -eq 202) # When I exit the above loop double check that it was a success (code 200) and throw some errors accordingly if ($output2.StatusCode -ne 200) { Write-Warning "Something went wrong:" Write-Warning $output2.Content } else { try { $results = $output2.Content | ConvertFrom-Json } catch { Write-Warning $output2.Content } # Do things with the results... } |
Neat!