Try-Catch pattern in Microsoft Flow
Recently I had a pleasure to show my presentation during Microsoft Flow Online Conference 2019 about building errorless workflows in Microsoft Flow. Actually, it was more about logging and debugging to receive errorless workflows in the end.
Watch the demo I presented during the conference below:
Anyone who has even a little experience with programming knows the “try – catch” pattern, usually substituted with “final” block. This construct is used to help handling errors in parts of the code, where programmers expect errors to occur. If error is caught, it wont’t trigger unhandled exception and push application into suspended mode, but can be caught and managed so that application operates without disturbance or at least user knows what to do.
The same approach can be used for Microsoft Flow. Even when we are authoring Flows trying to do our best, foreseen all possible exceptions in the ways Flow can run, still we can be surprised by situations totally independent from us, e.g. JSON body has changed and doesn’t match the schema, or secret key has expired and Flow gets access denied, or someone removed that item from database, that was used as a dictionary, or entity’s schema has changed and so on.
Try-Catch pattern in Microsoft Flow
When you are looking in the Internet how to implement such a pattern, you can fairly easy find already existing suggestions from:
- Rob Windsor: https://blogs.msmvps.com/windsor/2019/04/25/microsoft-flow-error-handling/
- Serge Luca: https://sergeluca.wordpress.com/2018/03/12/pattern-for-microsoft-flow-error-handling/
- Marcel Haas: https://www.thatmarcelhaas.com/post/advanced-error-handling-in-microsoft-flow
- Pieter Veenstra: https://veenstra.me.uk/2018/06/06/microsoft-flow-advanced-error-handling-throw-in-flow/
Oh, and there is already a template in Microsoft Flow templates gallery, you can simply use right away: https://flow.microsoft.com/en-us/galleries/public/templates/e8e028c6df7b4eb786abdf510e4f1da3/try-catch-and-finally-template/
The examples provided above are more or less complex, however they are all build around two functionalities of Microsoft Flow:
This feature is used to set up relationship and run sequence rules between actions. It lets you to set up that the next action should run if the previous: is completed successfully, has failed, is skipped or has timed out.
To access this setting simply click the epsilon icon (1) then from the menu click “Configure run after” (2), then define sequence relationship (3) and finally save your changes (4).
Scope is dedicated to group actions inside, so that later you can collapse it to make large workflow looking smaller and easier to “read”. It’s like a step in SharePoint Designer workflows. For the error handling scenario, they have also a second important role to play: if anything happens inside of them, they will reflect it like a mirror. If any error occurs inside a Scope, the whole Scope is errored. So they clearly show how the flow flows 😉
To add a scope simply click to add new action and then type “Scope”. Done.
Handling errors in Microsoft Flow
Run after and parallel block pattern
First approach bases only on “Run after” configuration and a parallel branch. To achieve it, simply add a parallel branch after the action you expect to fail, and then actions to both sides – e.g. correct flow on the left and send e-mail on the right:
Next, configure “Run after” of the action on the left side, so that it runs only, when previous completes successfully and then the one on right side, so that it runs only, when previous fails or is timed out, or skipped:
After all is configured fine, you’ll notice, that the right path is marked with red, dashed line, telling that its run after is set to run when previous action fails:
Run after and scopes pattern
This is the advanced configuration using three Scopes: “Try”, “Catch” and “Finally”. It follows the template existing here: https://flow.microsoft.com/en-us/galleries/public/templates/e8e028c6df7b4eb786abdf510e4f1da3/try-catch-and-finally-template/.
The “Try” scope should contain all the actions from the main flow of the process. “Catch” scope is configured to be run only if “Try” fails (for whichever reason). Then the “Finally” scope should run no matter what happens in previous actions:
Rob Windsor found, that there is a “
result()” function that can be used in Logic Apps. However since Flow is built on top, it is also available there. What this function does is getting a JSON array with execution details of a scope passed as a parameter. I am using it in “Catch” scope.
First I am filtering the array returned by the function “
result('Try')“. As I wrote – it contains all details about execution of each action form the “Try” scope. Filter action here is used to leave only items from array, that contains status Failed’, or ‘TimedOut’.
Next, for each such item I am appending its details to a text variable, that then is sent to me via e-mail, so that I have full details about errors.
In my case is used to always return response – because Flow is called via http request:
But depending on the scenario, response code is either 200 or set accordingly to the error that was caught by the “Catch” scope, e.g. 400 or 401.
Remember – you can use them as often inside a Flow as you need. You can as well implement multiple Try-Catch-Finally patterns inside a single Flow. It all depends on your specific requirements.
And that’s it! I hope you will find those patterns useful. If you need any support: leave me a comment or contact me!
Thanks a mill for the blog post as well!
Loved your session. 🙂
You’re welcome! I’m glad you liked it 🙂
I cannot follow your Try Catch example using different actions. In the Catch you filter the Array however you are not explaining the entire filter action. createArray(‘Failed’, “Timeout’) contains …. It seems you selected Dynamic Content that comes from you Trigger. I do not have the same trigger. Can give another filter array example? Or explain this further?
Yes, the Filter action is filtering this: “result(‘Try’)” using expression: “createArray(‘Failed’, ‘TimedOut’) contains item()[‘status’]” where the item-status has to by typed manually – it is to compare values of “status” from the filtered array.
Result function only returns 1 level of actions. How to get the error detail in further actions in try scope?
That is correct. Result function always returns data from the level below inside the container. If inside a scope you have another “container”, such as loop or condition, then actually you should use “result” and pass that container’s action name as a parameter.
Tomasz – Excellent pattern! Appreciate it.
Quick Question – what if we encounter an error during Catch or Finally block (for any reason). In that case I think MS Flow would behave in the default manner – isn’t it? It would “Terminate” as soon as it hits any error.
Yes. If there is an error in catch block Flow will behave by default. Therefore the point is to build your catch block to never fail, but to catch errors 🙂
Also, you can have multiple try-catch constructs if your flow is really complex.
Pingback: Power Automate Try Catch with Do Until - 365 Corner
Pingback: SharePoint 2010 workflows are retiring imminently… - Cloud Business
I am very intrigued by this but during my implementation when trying to put all my logic in a single scope and accurately report the errors I have noticed some issues. Not sure if you have seen these or have any thoughts around it.
For instance in a single scope I have a HTTP call, Parse JSON, a for Each loop which creates items in a SharePoint list. For testing a forced an error in 3 of the steps, HTTP, JSon and Create Item. Now here is where the interesting part comes in. All of there results are different so building a consistent message becomes difficult. At best I would be able to use the item().code, but that is not the best for detail. For the HTTP item within outputs there is a body element that contains errormessage and error code. For the Parse JSON there is a element named error that has code and message. For the ForEach/CreateItem, I dont see the error from the Create Item, just from the ForEachLoop and the code is just ActionFailed, not very specific.
I guess the question is, is this the best I can do or should I maybe break the 3 items into separate trys with separate catch’s so that I can build comprehensive error message?
Also, if you use scopes and other actions like conditions, loops, inner scopes then the report function result() sees is only at that container level. So that’s another issue.
Back to your question – yes, I also faced it. I am sometimes doing parallel branch to get values from different JSON models and merge it in the end.
Dziekuje Tomaszu/Thank you Tomasz.
I am trying to do this concept while catching the error on the SQL Insert row. Example is the database is wanting a number (phone number) but they enter in the phone number as (123)456-1234. So the insert fails since that is not a number. I know I could change the table to accept that and the Power Automate would work. But that also would change how we have to use that phone number. So get the phone number in the correct format to begin with works best. I know I can adjust the form to only be numbers between 1000000000 and 9999999999. But the concept is there for other issues. Just giving an example of an issue.
My issue is when the Insert Fails, it looks like it makes the whole FLOW fail. It is failing the :try” and never getting to the “CATCH” Is there a way to do the next step if the Insert fails?
Yes, you need to configure the “Run after” of the action that is directly after the insert action. You can set, that this action is executed even if insert failed.
Great Post !
I have an “Apply to Each” Control (writes 4 records to a SQL Server db). I added the Error Control (Try/Catch/Finally) and setup the ‘Configure Run After’.
The Flow executes and 2 records are written to the db. 2 other records get error because the Primary Key already exists in the db table (on purpose to cause error).
The error routine sends a notification for ALL 4 records. I only want it to send notifications for the 2 FAILED records (duplicate PK error) . How to solve ?
Hey, for that case the best option would be to implement the catch logging directly within the loop. So after an action is executed you need to add parallel branch, where one branch is executed (has its run after configuration) set up for successful execution, the other for an error. And in that where an error is handled, you can either append some string to a text variable, or send yourself notification. Up to you. In the end, as you noticed, whenever an error happens within an action that is a “block” type (scope, loop, condition, switch, etc…) that error is “mirrored” to the block level.