DEV Community

Cover image for Exception Handling in Power Automate
david wyatt
david wyatt

Posted on • Updated on

Exception Handling in Power Automate

Exception handling is key to all automations, as no matter how hard we try there will always be unexpected behaviour

The run after isn't the most intuitive exception handling I've seen (Blue Prism does it better), but once you used it a few times it's not too bad.

How To

Exception handling is configure in the run after setting. As good practice I recommend in most cases you should catch fails and timeouts.

Image description

Parallel branches can be used to divert and handle exceptions, with either the branch ending the flow or rejoining after handling the exception.
Scopes are key to exception handling, as they create a block that can be handled the same i.e if ay action fails within the Scope it will trigger the exception handling. Additionally wrapping all your exception actions within its own Scope ensures all those actions run.

Image description

The exception detail can be found and used with the following 2 expressions

actions() - For action exception
result() - For container (e.g scope/condition)

I recommend result() as catching exceptions from Scopesis easier. It returns an object of data:

{
    "from": [
        {
            "name": "Condition_Has_Attachment",
            "inputs": {
                "expressionResult": true
            },
            "startTime": "2023-01-08T18:25:51.8392646Z",
            "endTime": "2023-01-08T18:25:52.05801Z",
            "trackingId": "9999ec4-9999-9999-9999-33231c464c09",
            "clientTrackingId": "0858599999373166578219962773CU98",
            "status": "Succeeded"
        },
        {
            "name": "Delete_email_(V2)",
            "inputs": {
                "host": {
                    "apiId": "subscriptions/999931-9999-9999-9999-0b5042c8bada/providers/Microsoft.Web/locations/westus/runtimes/unitedstates-002/apis/office365",
                    "connectionReferenceName": "shared_office365_1",
                    "operationId": "DeleteEmail_V2"
                },
                "parameters": {
                    "messageId": "AAMkAGU4YmNlMGY4LWFjZDYtNDczMi05NDdhLTk0M2I5MjAzZmRmZgBGAAAAAABO9BLUWcxCTZzsiK9ugUPMBwC8DS3ucP99993qafeZHAAAAAAEMAAC8DS3ucPOGTZXMG3qafeZHAAAfSjgpAAA="
                }
            },
            "outputs": {
                "statusCode": 404,
                "headers": {
                    "Transfer-Encoding": "chunked",
                    "Vary": "Accept-Encoding",
                    "Strict-Transport-Security": "max-age=31536000",
                    "request-id": "999956fb-9999-9999-9999-3d70bcc74838",
                    "client-request-id": "999956fb-9999-4823-9999-3d70bcc74838",
                    "x-ms-ags-diagnostic": "{\"ServerInfo\":{\"DataCenter\":\"West US\",\"Slice\":\"E\",\"Ring\":\"4\",\"ScaleUnit\":\"001\",\"RoleInstance\":\"BY1PEPF00003E18\"}}",
                    "Timing-Allow-Origin": "*",
                    "x-ms-apihub-cached-response": "true",
                    "x-ms-apihub-obo": "false",
                    "Cache-Control": "private",
                    "Date": "Sun, 08 Jan 2023 18:26:20 GMT",
                    "Content-Type": "application/json",
                    "Content-Length": "370"
                },
                "body": {
                    "error": {
                        "code": "ErrorItemNotFound",
                        "message": "The specified object was not found in the store., The process failed to get the correct properties.",
                        "innerError": {
                            "date": "2023-01-08T18:26:21",
                            "request-id": "999956fb-9999-9999-9720-3d70bcc74838",
                            "client-request-id": "999956fb-9999-9999-9999-3d70bcc74838"
                        }
                    }
                }
            },
            "startTime": "2023-01-08T18:25:52.05801Z",
            "endTime": "2023-01-08T18:26:21.2375136Z",
            "trackingId": "c8481347-8c99-4334-a6eb-6153ce55344e",
            "clientTrackingId": "08585284045373166578219962773CU98",
            "code": "NotFound",
            "status": "Failed",
            "retryHistory": [
                {
                    "startTime": "2023-01-08T18:25:52.05801Z",
                    "endTime": "2023-01-08T18:26:15.9333579Z",
                    "code": "BadGateway",
                    "clientRequestId": "db499999-9999-9999-9999-f9999c3d7232"
                }
            ]
        }
    ],
Enter fullscreen mode Exit fullscreen mode

You can simply turn it to a string and pass it back, or use a Parse JSON and HTML/Markdown table to display it nicely.

The table is the easiest, I pass the action name, error reason and error description:

Image description

result('Main')

item()['name']

item()?['error']?['code']

item()?['error']?['message']

Image description


There are 3 different types/categories for exception handling

  • Process
  • Business
  • System

Process

Process exceptions are exception handling used as logic. So it's almost used as a condition, with the expectation the process will continue i.e. its not a real exception.

Image description

These are generally called try, catch, continue, and although very useful I'm personally not a fan. I would rather try standard logic to check and then not try, rather then try and deal with the error.

Business

Business exceptions are exceptions generated by input data, and are generally in loops. What's key about them is we don't want to end the process, we just want to flag that item as exception, and continue with the other items.

Image description

These generally only have one action, and may not need a Scope to contain them. Though to ensure the process continues the action after the loop would have to have run after Success and Failed enabled. A good example would be a to add a row to a SharePoint list, so that those items can be manually processed/corrected.

System

System exceptions are when something unexpected in the flow happens. Either a connector is failing due to the api or a key file can't be found. In these cases the process should carry out any clean up actions (e.g delete temp files) and escalate. This could be like a business exception with entry in a SharePoint list, but generally as its more serious I would recommend a teams message or email.

A good tip for system exceptions are:

Wrap the entire process in a Exception
Having a 'Main' Scope that contains every action means that a system exception after can catch any error in process. Although we mostly get failed emails from Power Automate, this is no good if running under a Service Account

Image description

Terminate after handling
Use the Terminate action set to fail, this allows you to still identify failed runs in the logs

Run link
The below expression creates a link to the failed run, so if added to the message/email, the user can click the link and go straight to the faile run. An added bonus is these links work longer then the normal retention (last 100 runs, I've got a link over a 1000 runs previous) and it can be accessed by environment admins without sharing the flow.

concat('https://make.powerautomate.com/manage/environments/', workflow()?['tags']?['environmentName'], '/flows/', workflow()?['name'], '/runs/', workflow()?['run']['name'])

Image description


Top comments (0)