---
description: Appmixer Engine Events.
---

# System Webhooks

### Component Errors

Components might throw exceptions. Such exceptions/errors are logged and users can see them in the [Insights](../api/insights). However, you might want to implement your custom logic or notification system for when this occurs. You may want to notify your users or handle/log the errors in a totally custom way.

If you want to listen for component errors you can set the `WEBHOOK_FLOW_COMPONENT_ERROR` environment variable to a URL that the Appmixer engine will send an HTTP POST request to whenever an error occurs. It can you any external (but accessible) URL or you can even create a flow in Appmixer and point this URL to a _Webhook_ component to handle these errors using Appmixer itself (e.g. by sending an email, Slack notification, ...).

Set the `WEBHOOK_FLOW_COMPONENT_ERROR` variable in the docker-compose.yml file:

```yaml
  engine:
    build:
      context: .
      dockerfile: Dockerfile
    depends_on:
      - mongodb
      - rabbitmq
      - elasticsearch
      - redis
    environment:
      # this variable has to point to your Webhook
      - WEBHOOK_FLOW_COMPONENT_ERROR=https://your.example.com/error-handling-ur
```

Example of an error POSTed to your URL (a validation error in this case):

```
{
    "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",
                    "gridInstanceId": null,
                    "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"
                    },
                    "correlationInPort": null,
                    "componentHeaders": {},
                    "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"
                }
            }
        ]
    },
    "accessTokenId": null
}
```

This error was triggered in a sample flow that looks like this:

![](https://1411580035-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LATDgYqVMe0hChW7efU%2F-MOVxYtxqUIajDvV9NtB%2F-MOVxhf8Bib6v1Ry87Rw%2FAppmixer.png?alt=media\&token=c407c1e0-2438-444b-aab8-1338bdc143ca)

The email address in the "To" configuration field of the _SendEmail_ component points to a variable from the _OnStart_ component. Its value is dynamic, it is only known during runtime. Therefore the user is allowed to start such a flow, but it will fail at runtime. _Start time_ variable contains a date string, but the _SendEmail_ address requires a valid email address in the _To_ input field. The error will be logged and seen in the log viewer.

![Log viewer in Designer.](https://1411580035-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LATDgYqVMe0hChW7efU%2F-MOVxYtxqUIajDvV9NtB%2F-MOVyX-XVJCVJq0ymJaz%2FAppmixer.png?alt=media\&token=6de93c94-ee51-45e3-a154-92c6b4c72be8)

Consider the flow is configured correctly this time and the email address is valid. But there is a network error and Appmixer cannot send the email.

![](https://1411580035-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LATDgYqVMe0hChW7efU%2F-MOVxYtxqUIajDvV9NtB%2F-MOW-e_FjAh3WmPTNGGU%2FAppmixer.png?alt=media\&token=3ea1e142-e5e7-4d57-a4cd-8f8e6b096826)

This error will be logged and the user will be able to see it in the log viewer or in the Insights. And the JSON representing this error will look like this:

```
{
    "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",
                    "gridInstanceId": null,
                    "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"
                    },
                    "correlationInPort": null,
                    "componentHeaders": {},
                    "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"
                }
            }
        ]
    },
    "accessTokenId": null
}
```

## Quota Limit Errors

If you have defined quota limits for the component and the limit has been reached then a Quota Error is posted to the error notification webhook. You can read more about Quotas and Limits [here](https://docs.appmixer.com/appmixer/component-definition/quotas-and-limits). Below is the example of the posted quota error which is raised when the weather API request quota limit has been reached. The `type` property will contain `quota` value. Appmixer will try to process such a message again. But too many of these notifications may indicate, that some flows are generating too many messages.

Single quota error does not necessarily mean something is wrong. Let's say a flow is writing rows into a Google Spreadsheet. And the flow is about to write 200 rows. There is a Google quota, a maximum of 60 requests at the same time. After writing 60 rows, the component will reach the quota limit and generate one of these notifications. But after some time, the quota will be available again and the component will write the remaining 140 rows.

```
{
    "err": {
        "message": "Ran out of quota for appmixer:utils:weather",
        "error":429,
        "data":429,
        "name":"QuotaError",
        "stack":"QuotaError: Ran out of quota for appmixer:utils:weather\\n    at Request._callback (/Driver.js:67:31)\"
    },
    "type": "quota",
    "flowId": "b7db896e-0e5c-4ee1-9cb3-1099c9f43b62",
    "flowName": "Daily Rainy Day Alert",
    "userId": "60ef4fd533d6143ba09c400f",
    "componentId": "13ad74e3-3354-463c-bf30-ea6e0c157ad8",
    "componentType": "appmixer.utils.weather.GetCurrentWeather",
    "inputMessages": {
        "location": [
            {
                "properties": {
                    "correlationId": '4dc33f4c-dbd0-4e97-ab05-381d785851f3',
                    "gridInstanceId": null,
        ...
            }
        ]
    }
}
```

## Forgot Password

Appmixer engine has an [API](../../api/user#forgot-password) to reset the forgotten passwords. The Forgot Password webhook is triggered whenever a user in the system requests for forgot password API. You can configure a webhook by setting the environment variable `WEBHOOK_USER_FORGOT_PASSWORD` to URL where the Appmixer engine will submit POST payload as follows.&#x20;

```
// WEBHOOK_USER_FORGOT_PASSWORD = 'http://hosted-url.com/events/forgot-password';

{
  'code': 'unique code generated for identifying forgot password request',
  'email': 'email address of user requesting for forgot password',
  'userId': 'USER id of user',
  'created': 'Date when a user requested for forgot password',
  'link': 'Link to access forgot password page on frontend'
}
```

{% hint style="info" %}
If forgot password webhook is configured as explained above, the Appmixer engine will not send the email to the user and trigger the webhook instead.
{% endhint %}
