Advanced error handling in Power Automate

Last month, I wrote about error handling in Power Automate and told you about the possibility of advanced error handling that I would be sharing later on.

In this blogpost, I will explain how to configure advanced error handling inside your flow.

Basic error handling summary

In my previous post, I explained how you can catch errors using the Run after conditions and sending a basic email when your flow has errored.

When explaining the advanced error handling, I will build further on this Christmas presents budget flow we created earlier (as shown above).

Advanced error handling

For advanced error handling, we need to modify our previous flow a bit before we can deep dive into it. This is because this functionality only works on actions bundled into some sort of container like a Scope, Condition, Apply to Each or Do Until. In this example, I’ll use the Scope.

Bundling actions

As mentioned, we need to put our process into a container, for which we use a Scope. But because you cannot initialize a variable into a container (only on top level), we need to add a Set variable action in which we calculate the budget per person (instead of directly into the initialize variable action). That Set variable action needs to be put into a Scope container. Make sure to clear the Value attribute of the Initialize variable numBudgetPerPerson action as well!

In the above screenshot, you can see that the Value attribute of the Initialize variable numBudgetPerPerson action has been cleared, a Scope called Calculate budget has been added and a Set variable action called Set variable numBudgetPerPerson to actual budget per person has been added into the Scope container.

This Set variable action sets the value of the variable to the calculation we did in our previous post (which previously was being set in the Initialize variable numBudgetPerPerson action):

div(
	variables('intTotalBudget'),
	triggerBody()?['number_1']
)

Where intTotalBudget is a static budget as set in the flow itself (in the Initialize variable intTotalBudget action) and number_1 is the amount of people input that will be asked when starting the flow.

result() expression

In order to deep dive into the errors that may occur in your flow, we need to make use the of the result() expression. This expression is not listed beneath the Expressions tab, nor will it show up under IntelliSense:

So, you’ll need to build the expression for yourself. Luckily, it isn’t that hard. It is result(<name of your container>) where each space character is handled as an underscore character. In our example, we called our Scope container Calculate budget, so our expression should be:

result('Calculate_budget')

When I put that expression in a Compose action and set the Run after condition of that action to run when the previous action (which is now our Scope container) has failed, you will see the outcome of this expression:

[
  {
    "name": "Set_variable_numBudgetPerPerson_to_actual_budget_per_person",
    "startTime": "2020-12-28T10:51:34.2736097Z",
    "endTime": "2020-12-28T10:51:34.2892337Z",
    "trackingId": "9568aea4-fce8-4e59-8da0-1e30a1868ce1",
    "clientTrackingId": "08585924541915168577730736438CU168",
    "clientKeywords": [
      "testFlow"
    ],
    "code": "BadRequest",
    "status": "Failed",
    "error": {
      "code": "InvalidTemplate",
      "message": "Unable to process template language expressions in action 'Set_variable_numBudgetPerPerson_to_actual_budget_per_person' inputs at line '1' and column '7550': 'Attempt to divide an integral or decimal value by zero in function 'div'.'."
    }
  }
]

As you can see, the expression will show you the details of each action inside the container. In our example we only have one action defined, so we only see the details of that action. If you have more actions inside your Scope, your JSON will contain all of these actions (even if the actions succeeded).

Now what’s interesting about these details, is the bottom section. In here you’ll see that the action has failed due to a bad request. And not only that, even the full error message has been provided to us here (you cannot divide a value by zero).

Processing the outcome

Now that we know how to extract the error details from an action, we need to correcly process this. As said, you can have multiple actions inside your container, thus multiple outcomes from your result() expression. For this reason, we need to add an Apply to each action that will loop through each action details. The output to use inside your Apply to each action is the same we just used in our Compose action:

result('Calculate_budget')

So you can just copy-paste it from the Compose action and remove the Compose action afterwards:

Within this Apply to each action, we can put all error information together. But since the result() expression will loop through each action, all successful actions will be processed as well, so we need to exclude them.

We can do this by adding a Condition that will check if the status attribute of the outcome is equal to Failed. Since the result() expression is not available from the expressions tab, the attributes aren’t either, so we need to manually configure this expression as well:

items('Apply_to_each_Scope_result')?['status']

When we put this into a Condition that will check if the value of the expression is equal to Failed, we now only get failed actions:

Now that we only process failed actions, we can proceed by collecting the information we want.

In this example, I want the name of the action and the actual error message. Because multiple errors may be possible (depending on the Run after condition set-up of your flow), I want each error message to be appended into a single variable so I can use that variable later on in an email.

For this, I need to Initialize a string variable action on top level (which I called varErrors) and an Append to string variable action inside the If yes branch of the Condition we just configured. As said, this Append to string variable action will contain the action name and the actual error message, of which the expressions are as follows:

Action name:

replace(
	items('Apply_to_each_Scope_result')?['name'],
	'_',
	' '
)

Since the name attribute contains the name of the action, but with underscores instead of spaces, the replace() function takes care of translating the underscores back to spaces.

Error message:

items('Apply_to_each_Scope_result')?['error']?['message']

Formatting this a bit more friendly to the eye into HTML, your Append to string variable will look like this:

Modifying the error mail

In the basic solution, we only sent an email containing basic information that the flow has failed. We can now modify this a bit so that the varErrors variable with details is being sent with it. For this, we need to transform the email into HTML format (because the varErrors variable is put into HTML format). In this example, I’ve configured it as follows:

Make sure the email is not inside the Apply to each action, but directly beneath it.

When you run the flow without anything filled in for the Amount of people input, your flow will fail and you will receive the following email:

Entire flow configuration

With everything in place, you now have configured a flow with advanced error handling. It should look like this:

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.