Reputation: 123
I am currently creating a workflow for work. I am retrieving data from an API using HTTP get, and handles it according to the status code. Apparently there is a bug in the API, so HTTP get always fails at the 24th iteration, with code 500.
I start with a simple Recurrence trigger, followed by initializing two variables, int pageNumber and bool continueLoop. I then have a Do Until loop, which continues to run until continueLoop becomes false. In the loop, I then send a HTTP GET request to the API. For each iteration of the loop, I use pageNumber to retrieve a page from the API. I then use a condition 'isValidStatusCode' to check if the HTTP GET status code is not 500.
If it is not, I parse the retrieved HTTP GET collection. I then check if the collection is 0 (Meaning i have iterated through all pages), and if so, I set continueLoop to false, which stops the loop. If not, i increment pageNumber for the next loop iteration.
If isValidStatusCode returns false, I will just ignore that page, increment the pageNumber, and start the loop again. Though this is where the issue arises. After isValidStatusCode False branch, the loop stops, but I need it to continue to run through the remaining pages.
As can be seen in the image, the loop runs 25 times before the issue arises. It should at least run 50+ times before stopping.
I have a condition called 'IGNORE', because i am just storing a insert row action that i am saving for later. the condition checks if 1=2, so it always returns false.
isValidStatusCode is set to run, even though HTTP-GET Collection fails.
The Image shows the 25th iteration of the loop. As you can see, isValidStatusCode returns false, and the loop terminates after running the false branch.
Code:
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Initialize_pageNumber": {
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "pageNumber",
"type": "integer",
"value": 1
}
]
},
"runAfter": {}
},
"Initialize_continueLoop": {
"type": "InitializeVariable",
"inputs": {
"variables": [
{
"name": "continueLoop",
"type": "boolean",
"value": true
}
]
"runAfter": {
"Initialize_pageNumber": [
"SUCCEEDED"
]
}
},
"Until": {
"type": "Until",
"expression": "@equals(variables('continueLoop'),false)",
"limit": {
"count": 30,
"timeout": "PT30S"
},
"actions": {
"HTTP-Get_Collection": {
"type": "Http",
"inputs": {
"uri": "page=@{variables('pageNumber')}&results=20",
"method": "GET",
"headers": {
"Authorization": "Bearer <token>",
"Content-Type\n": "application/json; charset=utf-8"
}
},
"runtimeConfiguration": {
"requestOptions": {
"timeout": "PT3S"
}
}
},
"isValidStatusCode": {
"type": "If",
"expression": {
"or": [
{
"not": {
"equals": [
"@outputs('HTTP-Get_Collection')?['statusCode']",
500
]
}
}
]
},
"actions": {
"Parse_Collection": {
"type": "ParseJson",
"inputs": {
"content": "@body('HTTP-Get_Collection')",
"schema": {
"type": "object",
"properties": {
"collection": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"contact": {
"type": "integer"
},
"subject": {
"type": "string"
},
"createdDate": {
"type": "string",
"format": "date-time"
},
"modifiedDate": {
"type": "string",
"format": "date-time"
},
"status": {
"type": "string"
}
},
"required": [
"id",
"contact",
"subject",
"createdDate",
"modifiedDate",
"status"
]
}
},
"pagination": {
"type": "object",
"properties": {
"count": {
"type": "integer"
}
},
"required": [
"count"
]
}
},
"required": [
"collection",
"pagination"
]
}
}
},
"If_collection_=_0": {
"type": "If",
"expression": {
"and": [
{
"equals": [
"@body('Parse_Collection')['collection']",
0
]
}
]
},
"actions": {
"Set_continueLoop_False": {
"type": "SetVariable",
"inputs": {
"name": "continueLoop",
"value": false
}
}
},
"else": {
"actions": {
"Increment_pageNumber_1": {
"type": "IncrementVariable",
"inputs": {
"name": "pageNumber",
"value": 1
}
}
}
},
"runAfter": {
"Parse_Collection": [
"SUCCEEDED"
]
}
}
},
"else": {
"actions": {
"Increment_pageNumber_2": {
"type": "IncrementVariable",
"inputs": {
"name": "pageNumber",
"value": 1
}
},
"IGNORE": {
"type": "If",
"expression": {
"and": [
{
"equals": [
1,
2
]
}
]
},
"actions": {
"Insert_row": {
"type": "ServiceProvider",
"inputs": {
"parameters": {
"tableName": "test"
},
"serviceProviderConfiguration": {
"connectionName": "sql-connection",
"operationId": "insertRow",
"serviceProviderId": ""
}
}
}
},
"else": {
"actions": {}
},
"runAfter": {
"Increment_pageNumber_2": [
"SUCCEEDED"
]
}
}
}
},
"runAfter": {
"HTTP-Get_Collection": [
"SUCCEEDED",
"FAILED",
"SKIPPED",
"TIMEDOUT"
]
}
}
},
"runAfter": {
"Initialize_continueLoop": [
"SUCCEEDED"
]
}
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"triggers": {
"Recurrence": {
"type": "Recurrence",
"recurrence": {
"interval": 1,
"frequency": "Hour",
"timeZone": "Romance Standard Time"
}
}
}
},
"kind": "Stateful"
}
Upvotes: 0
Views: 33
Reputation: 2858
It seems that your issue is that your loop always exists after the Http-Get action fails.
In order to prevent this from happening, you could wrap your Http-Get action (and the rest of the logic) in a Scope. You should be able to add it using the +
icon and using Add Action --> Scope.
Once you've moved your Http-Get Action and the rest of your logic into the Scope, use the ...
button for your newly created Scope and click on Configure run after. You should be able to set the Scope to run even if your action throws an exception, guaranteeing that the loop will continue to execute correctly.
Upvotes: 0