Welcome again to another Logic Apps Best practices, Tips, and Tricks. In my previous blog posts, I talked about some of the most essential best practices you should have while working with the Azure Logic App:
And some tips and tricks:
- #4 Using Scopes
- #5 Delete comments
- #6 Error handling configure run after settings
- #7 Learn from failures
- #8 Expressions nightmare
- #9 Control your connectors (API connections)
- #10 Fix connectors (or API connections)
- #11 Connectors naming convention
- #12 Choose your developer tools properly
- #13 Logic App (Standard) vs (Consumption)
- #14 Implement good governance policies
Today I’m going to speak about another important Best practice, Tips, and Tricks that you need to know when you start developing your Logic App solutions: How to get the proper error message from a Logic App failure?
It is pretty standard that when a Logic App fails, we want to get the exact and clear error message describing why it failed. Of course, we can always go to the Logic App run history – except if it is a Stateless workflow on Standard – to check where and why it failed. And obviously, we will have all the information necessary to solve the problem. But we all know that we need to automate the process and record these errors on our monitoring and alarming platform some place like Application Insights, SQL Database, Event Hubs, etc. To accomplish that, of course we need to access this error message in runtime.
As I explained in one of my previous Logic App Best practices, Tips and Tricks: #6 Error handling configure run after settings. We can implement advanced Error handling capabilities like:
- Creating a try-catch statement consisting of a try block followed by one catch clause to handlers different exceptions that can occur on the try block.
- Or creating a try-catch-finally statement.
And for that, we have to use a combination of different Scopes.
The try-catch-finally statement handles all of the errors that may occur in a block of code. Errors can be coding errors made by the programmer, errors due to wrong input, and other unforeseeable things.
- The try statement allows you to define a block of code to be tested for errors while it is being executed –> this will be your Actions inside Logic App that describe the logic of your business process.
- The catch statement allows you to define a block of code to be executed if an error occurs in the try block –> this will be your Actions inside Logic App that your want to run if some failure occurs in the standard actions of your business process.
- The finally statement lets you execute code after try and catch statements, regardless of the result (if there was a fail inside the try statement or if everything was completed successfully).
We can say that this tip is a continuation of tip number 6.
Now inside the catch scope, we will have an action logging the error, but before we call it, we need to get the detailed error message. Something similar to the e.Message that we normally do in our .NET code
Approach 1: Using the result() function
To do this, we must first filter the run action status result for Failed items. For that, the Logic App runtime has a Workflow function call result that can return the inputs and outputs from the top-level actions inside the specified scoped action, such as
So, inside of our Catch Scope, add the following action:
- Inside the Catch scope, select Add an action.
- In the search box, enter Filter array, and then select the Data Operations, Filter array action. Then provide the following information:
- on the From property, add the following expression
- Note: that ‘Try_scope’ is the name of the previous scope, so you need to adjust this value to your scenario
- on the condition, place the following expression
- Note: this is always the same
- Leave the operator as is equal to, and on the right textbox, add the following value:
- on the From property, add the following expression
Because this only brings the results of the top-level actions, what we want to grab is the first error that is reported there. To do that, we need to, for example, set a variable with the error message present in the previous action output.
- Assuming that we already have a variable initialized. Select Add an action.
- In the search box, enter Variables, and then select the Variables, Set variable action.
- On the variable shape, select the variable we want to use, and on the value, set the following expression:
This is a simple approach that you can use for simple and straightforward business processes that don’t contain conditions or loops. However, if you are creating more enterprise processes, they will be more complicated and we normally have nested conditions, conditions inside the loops, and so on. In that cases, this approach will not work.
You can find more details about this approach here: How to get the Error Message with Logic App Try-Catch (Part I).
Approach 2: Using an Azure Function
There is a good post by Mike Stephenson describing this approach: Cleaner Error Message with Logic App Try-Catch using a Function. The problem of approach 1 is that result() function will only get the top-level action descriptions, and all child errors will be translated to:
- ActionFailed. An action failed. No dependent actions succeeded.
You have at least to options on the table to address and solve this issue:
- Using a code-first approach by using an Azure Function – is the approach we will be explaining here today.
- and using a no-code, low-code approach by using a Logic App (same code logic but using a Logic App)
Globally, this approach works like this:
- For each failure, we will implement a try/catch pattern in the usual way, but in the catch block, we will call a function and pass the:
- id for the run of the logic app.
- Subscription Id
- Resource Name
- Logic App name
- In the function, we will then call the Azure Management REST API and use a filter to get the actions that have a failed status.
- We will then loop through them (the errors), and we will remove the ones where the message is “An action failed. No dependent actions succeeded” because these are usually scope shapes with an error inside them and are just noise. And we want just the actual errors.
- For each action that is a genuine error, we will then use the properties to get the link to the message body and call it to get the underlying error message from the action.
- In the end, we will then return an array of the errors within the Logic App run.
You can find more details about this approach here: How to get the Error Message with Logic App Try-Catch (Part II) – Using an Azure Function.
I hope you have enjoyed it! Stay tuned for the following Logic App Best practices, Tips, and Tricks.