Dear Experts. 😊
I hope this is the right place/channel.
We have been using a custom connector in Power Automate for a while now. The endpoint is an Azure Function. This works fine.
Now, some of the operations can take a while depending on the input, so I have been looking into implementing the http async pattern.
I started extending the Azure function using durable functions and that also works ok, but they do not seem to match up with what the Power Automate caller/invocation expects.
Durable functions return a Microsoft.Azure.WebJobs.Extensions.DurableTask.DurableOrchestrationStatus (json) object when complete and Power Automate does not appear to know how to unwrap this to yield only the output part of this.
Example response:
{
"statusCode": 200,
"headers": {
"Vary": "Accept-Encoding",
"Request-Context": "appId=cid-v1:8e4fcdf4-ed31-4196-8e4a-d3e3b9f94bb1",
"Date": "Tue, 08 Dec 2020 11:24:21 GMT",
"Content-Type": "application/json; charset=utf-8",
"Content-Length": "2253"
},
"body": {
"name": "WhoAmI_Orchestrator",
"instanceId": "4267e61e2a4649d1b06e981519a9733c",
"runtimeStatus": "Completed",
"input": {
"Authorization": "***",
"WebFullUrl": "https://sxyz.sharepoint.com/sites/jco"
},
"customStatus": null,
"output": {
"Title": "*Obfuscated Name*",
"LoginName": "i:0#.f|membership|jco@xyz.dev",
"Email": "jco@ xyz.dev"
},
"createdTime": "2020-12-08T11:24:09Z",
"lastUpdatedTime": "2020-12-08T11:24:12Z"
}
}
This may be something that we could work around, but the thing that I really struggle with is how to make Power Automate understand when a request has failed. Of all the examples and documentation I have found anywhere, there is no error handling in this scenario.
When Power Automate receives the following response from the function status endpoint, it happily accepts it as a success without any notion that the runtimeStatus is failed.
{
"statusCode": 200,
"headers": {
"Vary": "Accept-Encoding",
"Request-Context": "appId=cid-v1:8e4fcdf4-ed31-4196-8e4a-d3e3b9f94bb1",
"Date": "Tue, 08 Dec 2020 11:51:25 GMT",
"Content-Type": "application/json; charset=utf-8",
"Content-Length": "4449"
},
"body": {
"name": "WhoAmI_Orchestrator",
"instanceId": "dfd429917296412ebe107938dc93b641",
"runtimeStatus": "Failed",
"input": {
"Authorization": "***",
"WebFullUrl": "https://xyz.sharepoint.com/sites/cs-dms-demo1"
},
"customStatus": {
"Type": null,
"Title": "The remote server returned an error: (401) Unauthorized.",
"Status": 400,
"Detail": "Lms365.CS.Function.Controllers.ControllerException: The remote server returned an error: (401) Unauthorized.\r\n[*cut short*]",
"Instance": null,
"Extensions": {}
},
"output": "Orchestrator function 'WhoAmI_Orchestrator' failed: The remote server returned an error: (401) Unauthorized.",
"createdTime": "2020-12-08T11:51:14Z",
"lastUpdatedTime": "2020-12-08T11:51:16Z"
}
}
Now, Durable functions have a setting that allows them to set http status code “500 Internal Server Error” on failure (returnInternalServerErrorOnFailure). Trouble is that Power Automate (incorrectly) assumes that all status codes 5xx should be retried (it may be valid to retry “503 Service Unavailable”). Therefore, there will be a 10-minute delay before the user gets the actual error while Power Automate retries the operation.
To try and work around this, I made my own implementation for the status endpoint while still using the underlying durable function mechanics. This way I can control the output and status code of the successful operation, but when I return http status 400 Bad Request along with some error details (Microsoft.AspNetCore.Mvc.ProblemDetails), this is surprisingly captured as a 404 Not Found without any further details by Power Automate. The same goes if I send a 302 Found with a location to a different URL that contains the actual result (or error) depending on the outcome.
This article does not speak of redirection at the end:
https://docs.microsoft.com/en-us/azure/logic-apps/logic-apps-create-api-app#perform-long-running-tasks-with-the-polling-action-pattern
This resource suggests using 302/303 redirect result codes:
https://docs.microsoft.com/en-us/azure/architecture/patterns/async-request-reply
To debug my way to a solution, I created a logic app, but found that the results were the same and it didn’t give me the necessary information.
I suspect that there are custom status headers that can be returned to Power Automate to signal that an operation has failed, but I simply cannot find any information on it.