By default a failed action stops the flow and marks the run as failed. That sounds reasonable until the failure happens at step nine of twelve, after records were created but before they were linked, and the only notification is a run history nobody checks.
Power Automate has no try/catch keyword, but it has everything needed to build one.
The shape: three scopes
- Try: a Scope containing the real work.
- Catch: a Scope that runs only when Try fails. It logs, notifies and cleans up.
- Finally: an optional Scope that always runs, for anything that must happen either way.
The behaviour comes from Configure run after, on each action menu. By default an action runs only if the previous one succeeded. Change that, and the flow branches on the outcome.
- On Catch, clear is successful and tick has failed and has timed out.
- On Finally, tick all four outcomes: is successful, has failed, is skipped and has timed out.
Getting the real error message
Inside Catch, the question is what went wrong. The result() function returns the outcome of every action inside a scope, including its status and error details. Filter it down to the failures with a Filter array action.
@result('Try')@equals(item()?['status'], 'Failed')Then build a readable message from the first failure:
@{first(body('Filter_array'))?['name']}: @{first(body('Filter_array'))?['error']?['message']}Some connectors put the detail in the action outputs rather than in error, so when in doubt log the whole failed item. Add a link straight to the run as well, so whoever reads the alert can open it in one click:
https://make.powerautomate.com/environments/@{workflow()?['tags']?['environmentName']}/flows/@{workflow()?['name']}/runs/@{workflow()?['run']?['name']}The step most flows forget
A Catch scope that completes marks the whole run as Succeeded. The error was handled, so as far as the run history is concerned nothing went wrong, and anyone watching for failed runs never sees it.
End Catch with a Terminate action set to Failed, carrying the message you composed. The notification still goes out, and the run history tells the truth.
Retries before catches
Not every failure deserves the Catch path. Throttling and brief network errors usually resolve on their own, and the default Retry policy in each action already retries transient failures. Check it before adding alerts, so nobody gets paged about a request that would have succeeded a minute later.
Three scopes, two run-after settings, one expression and a Terminate. It takes ten minutes to add, and it turns a silent partial failure into a message someone can act on.




