Handle Flow Errors

When errors arise in running automations or integrations, Appmixer does not automatically send emails to your end-users. Instead, it offers complete customization of communication with your end-users, enabling you to send your own branded emails or other types of notifications. This approach allows you to maintain consistency in your communication strategy and ensure that all messages align with your brand identity.

It's worth noting that you can set up your own Appmixer automation to manage error notifications. Simply utilize the Webhook trigger as the starting point for your automation and register the Webhook URL with the WEBHOOK_FLOW_COMPONENT_ERROR System Webhook configuration in the Backoffice. This method allows you to automate the notification process effectively, tailoring it to meet your specific needs and and avoid implementing a new endpoint in your own backend application.

To manage errors within running integrations or automations, configure the WEBHOOK_FLOW_COMPONENT_ERROR system variable with a custom URL in the Appmixer Backoffice interface. Appmixer will then send an HTTP POST request to this URL each time an error occurs in a flow, enabling you to respond or notify as necessary based on the error details provided. This setup provides a streamlined way to monitor and address issues in real-time.

The payload that Appmixer sends to the registered URL when an error occurs in a flow has the following structure:

{
    "err": {
        "message": "Validation error on ports: in",
        "code": "GRID_ERR_VAL_PORTS",
        "name": "ValidationFlowError",
        "stack": "ValidationFlowError: Validation error on ports: in\n    at MessagesProcessor.process (/Users/martinkrcmar/Programming/client/appmixer/appmixer-core/engine/src/context/MessagesProcessor.js:67:19)\n    at Context.prepare (/Users/martinkrcmar/Programming/client/appmixer/appmixer-core/engine/src/context/Context.js:68:31)\n    at ContextHandler.createContext (/Users/martinkrcmar/Programming/client/appmixer/appmixer-core/engine/src/context/ContextHandler.js:60:17)\n    at async InputQueue.consume (/Users/martinkrcmar/Programming/client/appmixer/appmixer-core/engine/src/InputQueue.js:151:23)\n    at async InputQueue.onMessage (/Users/martinkrcmar/Programming/client/appmixer/appmixer-core/engine/src/AMQPClient.js:378:20)"
    },
    "type": "component",
    "flowId": "32f605b2-8fbe-4f68-9db9-ce182b35c159",
    "flowName": "New flow",
    "userId": "5f804b96ea48ec47a8c444a7",
    "componentId": "0bb33e42-fbc4-464e-98f1-459f1ff626ac",
    "componentType": "appmixer.utils.email.SendEmail",
    "inputMessages": {
        "in": [
            {
                "properties": {
                    "correlationId": "339bc448-a806-4e61-8d38-4211fcedaf12",
                    "contentType": "application/json",
                    "contentEncoding": "utf8",
                    "sender": {
                        "componentId": "e8c581b4-9985-4f2c-bf30-895bf1d5541b",
                        "type": "appmixer.utils.controls.OnStart",
                        "outputPort": "out"
                    },
                    "destination": {
                        "componentId": "0bb33e42-fbc4-464e-98f1-459f1ff626ac",
                        "inputPort": "in"
                    },
                    "flowId": "32f605b2-8fbe-4f68-9db9-ce182b35c159",
                    "messageId": "47293e2c-4e33-4558-8805-386de392ef04",
                    "flowRunId": 1607683798995
                },
                "content": {
                    "to": "2020-12-11T10:49:59.050Z"
                },
                "scope": {
                    "e8c581b4-9985-4f2c-bf30-895bf1d5541b": {
                        "out": {
                            "started": "2020-12-11T10:49:59.050Z"
                        }
                    }
                },
                "originalContent": {
                    "started": "2020-12-11T10:49:59.050Z"
                }
            }
        ]
    }
}

Recommendation for End-User Error Notification Content

While the error message from Appmixer provides comprehensive details about the issue, it's important to communicate this information to your end-users in a more digestible format. To ensure your notifications are user-friendly and avoid overwhelming your end-users with technical jargon, we recommend structuring your communications as follows:

Example: Data Validation Error

Given a scenario where the SendEmail component in a flow mistakenly references the Start time output of the OnStart trigger instead of an email address in the To field, a runtime error will occur. This mistake results in the flow attempting to use a timestamp as the recipient's email address, which is invalid. Consequently, this misconfiguration triggers a runtime error, which is then accurately recorded and can be reviewed in the log viewer.

When an unrecoverable error occurs, such as the one described with the SendEmail component misconfiguration, Appmixer will package the error details into a JSON object. This JSON payload is then sent via an HTTP POST request to the URL specified in the WEBHOOK_FLOW_COMPONENT_ERROR system variable. The structure of this payload is designed to provide comprehensive information about the error, including the component that caused it, the nature of the error, and any relevant data to identify and address the issue:

{
    "err": {
        "message": "Validation error on ports: in",
        "error": {
            "in": [
                [
                    {
                        "keyword": "format",
                        "dataPath": ".to",
                        "schemaPath": "#/properties/to/format",
                        "params": {
                            "format": "email"
                        },
                        "message": "should match format \"email\""
                    }
                ]
            ]
        },
        "code": "GRID_ERR_VAL_PORTS",
        "name": "ValidationFlowError",
        "stack": "ValidationFlowError: Validation error on ports: in\n    at MessagesProcessor.process (/Users/martinkrcmar/Programming/client/appmixer/appmixer-core/engine/src/context/MessagesProcessor.js:67:19)\n    at Context.prepare (/Users/martinkrcmar/Programming/client/appmixer/appmixer-core/engine/src/context/Context.js:68:31)\n    at ContextHandler.createContext (/Users/martinkrcmar/Programming/client/appmixer/appmixer-core/engine/src/context/ContextHandler.js:60:17)\n    at async InputQueue.consume (/Users/martinkrcmar/Programming/client/appmixer/appmixer-core/engine/src/InputQueue.js:151:23)\n    at async InputQueue.onMessage (/Users/martinkrcmar/Programming/client/appmixer/appmixer-core/engine/src/AMQPClient.js:378:20)"
    },
    "type": "component",
    "flowId": "32f605b2-8fbe-4f68-9db9-ce182b35c159",
    "flowName": "New flow",
    "userId": "5f804b96ea48ec47a8c444a7",
    "componentId": "0bb33e42-fbc4-464e-98f1-459f1ff626ac",
    "componentType": "appmixer.utils.email.SendEmail",
    "inputMessages": {
        "in": [
            {
                "properties": {
                    "correlationId": "339bc448-a806-4e61-8d38-4211fcedaf12",
                    "contentType": "application/json",
                    "contentEncoding": "utf8",
                    "sender": {
                        "componentId": "e8c581b4-9985-4f2c-bf30-895bf1d5541b",
                        "type": "appmixer.utils.controls.OnStart",
                        "outputPort": "out"
                    },
                    "destination": {
                        "componentId": "0bb33e42-fbc4-464e-98f1-459f1ff626ac",
                        "inputPort": "in"
                    },
                    "flowId": "32f605b2-8fbe-4f68-9db9-ce182b35c159",
                    "messageId": "47293e2c-4e33-4558-8805-386de392ef04",
                    "flowRunId": 1607683798995
                },
                "content": {
                    "to": "2020-12-11T10:49:59.050Z"
                },
                "scope": {
                    "e8c581b4-9985-4f2c-bf30-895bf1d5541b": {
                        "out": {
                            "started": "2020-12-11T10:49:59.050Z"
                        }
                    }
                },
                "originalContent": {
                    "started": "2020-12-11T10:49:59.050Z"
                }
            }
        ]
    }
}

Example: Network Error

If the flow is configured correctly with a valid email address but encounters a network error preventing Appmixer from sending the email, this situation represents a temporary or external issue rather than a misconfiguration within the flow itself. In such cases, Appmixer will attempt to handle the error based on its retry policies or error-handling mechanisms. If the error persists and is deemed unrecoverable for that instance of execution, Appmixer may report this failure through the WEBHOOK_FLOW_COMPONENT_ERROR system variable, if configured. The notification sent to the specified webhook URL will detail the error, indicating it was a network issue affecting the email send action, allowing for appropriate troubleshooting or user notification.

Users can then review this error within the log viewer or under Insights, where all flow activities and errors are documented for analysis.

Appmixer sends out a JSON payload to the registered URL containing detailed information about the error:

{
    "err": {
        "stack": "Error: getaddrinfo ENOTFOUND mandrillapp.com\n    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:66:26)",
        "message": "getaddrinfo ENOTFOUND mandrillapp.com",
        "errno": "ENOTFOUND",
        "code": "ENOTFOUND",
        "syscall": "getaddrinfo",
        "hostname": "mandrillapp.com",
        "name": "Error"
    },
    "type": "component",
    "flowId": "0ab287ef-7bd6-4cc3-b53b-c916c857cbe7",
    "flowName": "Invalid email test",
    "userId": "5fd744d5e9ed7d0011ca35f9",
    "componentId": "cb3f4ff5-7b6e-4d24-b7a8-2115c8254baa",
    "componentType": "appmixer.utils.email.SendEmail",
    "inputMessages": {
        "in": [
            {
                "properties": {
                    "correlationId": "254ad628-f9c1-4483-81ed-33a22ac3ddc6",
                    "contentType": "application/json",
                    "contentEncoding": "utf8",
                    "sender": {
                        "componentId": "bcbeda1d-9036-45af-a25d-a57cf06e3f90",
                        "type": "appmixer.utils.controls.OnStart",
                        "outputPort": "out"
                    },
                    "destination": {
                        "componentId": "cb3f4ff5-7b6e-4d24-b7a8-2115c8254baa",
                        "inputPort": "in"
                    },
                    "flowId": "0ab287ef-7bd6-4cc3-b53b-c916c857cbe7",
                    "messageId": "33b9fcbf-b326-4eb4-bba6-cf34979f4ba2",
                    "flowRunId": 1607944841843,
                    "quotaId": "qs-4882d03d-65e1-44dc-983e-d2a33071779d"
                },
                "content": {
                    "to": [
                        {
                            "email": "martin@client.io",
                            "type": "to"
                        }
                    ],
                    "from_email": "no-reply@appmixer.com"
                },
                "scope": {
                    "bcbeda1d-9036-45af-a25d-a57cf06e3f90": {
                        "out": {
                            "started": "2020-12-14T11:20:41.858Z"
                        }
                    }
                },
                "originalContent": {
                    "started": "2020-12-14T11:20:41.858Z"
                }
            }
        ]
    }
}

It's important to note that Appmixer employs an automatic retry mechanism for handling network errors when sending messages. This involves multiple attempts to resend the message, following an exponential backoff strategy to optimize the timing of retries. Thus, the error notification sent via the WEBHOOK_FLOW_COMPONENT_ERROR system variable, along with the detailed JSON payload to the registered URL, occurs only if all retry attempts fail. This approach ensures that temporary issues have ample opportunity to be resolved before escalating the error, aiming to maintain the reliability of your automations and integrations without immediate interruption from transient network issues.

Last updated