Logic apps and functions together
I was recently doing a small scale integration between Azure Functions and Azure Logic Apps. In this case I wanted to control retry behavior of Logic Apps HTTP actions. Below are my findings related to error handling and producing desired behavior in Logic Apps – Also ensuring that I can replicate the error handling with other clients, not just Logic Apps.
Default behavior
Default behavior of Logic Apps was in charge of the retry behavior. This caused more retries than I felt was necessary when faced with HTTP response code 500. Especially since unhandled errors would cause the Azure Function to respond with 500, which caused long time until it would show as fail
- There is also internal way to control the retries from Logic Apps. In this case I didn’t take that route, for reasons explained in ending words
The remediation
First change I made was to identify errors which we’re catch-able (known errors), and handle them in try catch block.
//Tro to initialize storage before continuing with the function
try { var {getSasUrl} =require(`${__dirname}/src/storageAccess`)
} catch (error) {
//return 400, so to stop Logic App from retrying
var result = `${error}`
return context.res = {
status:400,
body: {
result,
reason:'Ensure KeyVault reference is correct for Azure Storage found:' + KeyVaultReferenceFound,
}
};
}
In this case both of the two predictable errors were interdependent related to likely misconfiguration of NodeJS Azure Storage SDK
- Storage SDK not initialized in Azure Functions due invalid credentials, or non provided credentials
- KeyVault reference has wrong ENV variable name setup in the Environment variables

#No Storage SDK credentials found { "result": "Error: Credentials must be provided when creating a service client.", "reason": "Ensure KeyVault reference is correct for Azure Storage found:undefined" } #Credentials found but in wrong format { "result": "SyntaxError: Connection strings must be of the form \"key1=value1;key2=value2\".", "reason": "Ensure KeyVault reference is correct for Azure Storage found:AZURE_STORAGE_CONNECTION_STRING" } # Invalid key format { "result": "SyntaxError: The provided account key is not a valid base64 string.", "reason": "Ensure KeyVault reference is correct for Azure Storage found:AZURE_STORAGE_CONNECTION_STRING" }
HTTP 400 or 500
The second change was to lookup HTTP code, that would tell the Logic Apps action, that ’The client SHOULD NOT repeat the request without modifications’ Turns out this is in spec of status code 400, and Logic Apps HTTP request aligns with the spec
- Per spec it’s actually targeted to identify bad request at the client side. In this case, the error was actually in the API which would originally be per spec be HTTP 500, but HTTP 400 provided the key use case for me, to control retry behavior of Logic Apps
Its also good to understand, that this doesn’t deny server responding with 500 when there is other error which is caused by the platform, or runtime itself. Such as transient errors, or error during startup, in these cases the retry behavior is desired to an extent.

The result of remediation
- Failing is much faster, and I control the retry behavior from function side

Ending words
Stopping retry behavior with 400 is typically used, when the client request is wrong, in this case the behavior is also produced in select errors of the NodeJS API (Azure Function)
Logic Apps allow also controlling retry policy in Logic Apps design. This is probably the best practice in the end. In my case I wanted to ensure, that the retrying is stopped even if the caller is not Logic Apps. This tries to ensure that if the client calling doesnt have retry behavior settings, then at least if it aligns with the specification of HTTP400, it shouldn’t retry the request.
ref https://docs.microsoft.com/en-us/azure/logic-apps/logic-apps-exception-handling

Paluuviite: Azure Logic Apps – Handling retry behavior with response codes in NodeJS Function (HTTP 400, or 500) > Seekalgo