{
  "id": "YybYYc430rmZWJPJ",
  "meta": {
    "instanceId": "febfa0961d1e55a48938f0337f348b73a50538aa16673607611ead85d95f662c",
    "templateCredsSetupCompleted": true
  },
  "name": "Log errors and avoid sending too many emails",
  "tags": [
    {
      "id": "7YoU4oTsaGGEtWJj",
      "name": "sample",
      "createdAt": "2025-01-31T16:41:27.407Z",
      "updatedAt": "2025-01-31T16:41:27.407Z"
    }
  ],
  "nodes": [
    {
      "id": "0e44df4c-00d2-4545-89ae-844a590de369",
      "name": "Error Trigger",
      "type": "n8n-nodes-base.errorTrigger",
      "position": [
        -1200,
        90
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "7101542a-5146-4917-a1f2-13686cad197e",
      "name": "Insert Log",
      "type": "n8n-nodes-base.postgres",
      "position": [
        -980,
        40
      ],
      "parameters": {
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "N8Err",
          "cachedResultName": "N8Err"
        },
        "schema": {
          "__rl": true,
          "mode": "name",
          "value": "p1gq6ljdsam3x1m"
        },
        "columns": {
          "value": {
            "URL": "={{ $json.execution.url }}",
            "json": "={{ JSON.stringify($json) }}",
            "Stack": "={{ $json.execution.error.stack }}",
            "title": "={{ $json.workflow.name }}",
            "Message": "={{ $json.execution.error.message }}",
            "LastNode": "={{ $json.execution.lastNodeExecuted }}",
            "created_at": "={{ $now }}"
          },
          "schema": [
            {
              "id": "id",
              "type": "number",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "id",
              "defaultMatch": true,
              "canBeUsedToMatch": true
            },
            {
              "id": "created_at",
              "type": "dateTime",
              "display": true,
              "required": false,
              "displayName": "created_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "updated_at",
              "type": "dateTime",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "updated_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "created_by",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "created_by",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "updated_by",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "updated_by",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "nc_order",
              "type": "number",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "nc_order",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "title",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "URL",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Stack",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Stack",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "json",
              "type": "object",
              "display": true,
              "required": false,
              "displayName": "json",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Message",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Message",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "LastNode",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "LastNode",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "credentials": {
        "postgres": {
          "id": "2VsRB7eDnG0FA3z2",
          "name": "Postgres Nocodb"
        }
      },
      "typeVersion": 2.6
    },
    {
      "id": "8fb1201c-353e-466c-8d08-fd969e6b10b1",
      "name": "Count for 5 minutes",
      "type": "n8n-nodes-base.postgres",
      "position": [
        -980,
        -210
      ],
      "parameters": {
        "query": "SELECT count(*) FROM p1gq6ljdsam3x1m.\"N8Err\" where created_at >= $1;\n",
        "options": {
          "queryReplacement": "={{ $now.minus(5, 'minutes').toString() }}"
        },
        "operation": "executeQuery"
      },
      "credentials": {
        "postgres": {
          "id": "2VsRB7eDnG0FA3z2",
          "name": "Postgres Nocodb"
        }
      },
      "typeVersion": 2.6
    },
    {
      "id": "89f836dc-8141-4c20-a758-bf7ff261a87b",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2260,
        -300
      ],
      "parameters": {
        "color": 5,
        "width": 820,
        "height": 1140,
        "content": "# Log errors and avoid sending too many emails\n\n## Use case\n\nMost of the time, it’s necessary to log all errors that occur. However, in some cases, a scheduled task or service consuming excessive resources might trigger a surge of errors.\n\nTo address this, we can log all errors but limit alerts to a maximum of one notification every 5 minutes.\n\n## What this workflow does\n\nThis workflow can be configured to receive error events, or you can integrate it **before your own error-handling logic.**  \n\nIf used as the **primary error handler**, note that this flow will **only add a database log entry** and take no further action. You’ll need to add your own alerts (e.g., email or push notifications). Below is an example of a notification setup I prefer to use.  \n\nAt the end, there’s an **error cleanup** option. This feature is particularly useful in development environments.  \n\nIf you already have an error-handling workflow, you can call this one as a **sub-workflow**. Its final steps include cleanup logic to reset the execution state and terminate the workflow.\n\n## Setup\n\n**Verify all Postgres nodes and credentials when using the 'Error Handling Sample'**\n\n## How to adjust it to your needs\n\n1) You can set this workflow as a sub-workflow within your existing error-handling setup.\n\n2) Alternatively, you can add the \"Error Handling Sample\" at the end of this workflow, which sends email and push notifications.\n\nConfiguration Requirements:\n\n⚠️ You must create a database table for this to work!\n\n\n\nDDL of this sample:\n\ncreate table p1gq6ljdsam3x1m.\"N8Err\"\n(\n    id         serial\n        primary key,\n    created_at timestamp,\n    updated_at timestamp,\n    created_by varchar,\n    updated_by varchar,\n    nc_order   numeric,\n    title      text,\n    \"URL\"      text,\n    \"Stack\"    text,\n    json       json,\n    \"Message\"  text,\n    \"LastNode\" text\n);\n\nalter table p1gq6ljdsam3x1m.\"N8Err\"\n    owner to postgres;\n\ncreate index \"N8Err_order_idx\"\n    on p1gq6ljdsam3x1m.\"N8Err\" (nc_order);\n\nby Davi Saranszky Mesquita\nhttps://www.linkedin.com/in/mesquitadavi/"
      },
      "typeVersion": 1
    },
    {
      "id": "fba7fec5-5285-46bd-9cc7-270b7dcc8c5f",
      "name": "Principal E-Mail",
      "type": "n8n-nodes-base.emailSend",
      "onError": "continueErrorOutput",
      "disabled": true,
      "position": [
        -980,
        350
      ],
      "webhookId": "d76d2e82-b0a8-4e35-88f9-1815d4ce6c79",
      "parameters": {
        "text": "={{ $(\"Error Trigger\").item.json.execution.url }}\n\n{{ $(\"Error Trigger\").item.json.execution.lastNodeExecuted }}\n\n{{ $(\"Error Trigger\").item.json.execution.error.message }}\n{{ $(\"Error Trigger\").item.json.execution.error.stack }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "=Erro -  {{ $(\"Error Trigger\").item.json.workflow.name }}",
        "toEmail": "davimesquita@gmail.com",
        "fromEmail": "suporte@ideias.casa",
        "emailFormat": "text"
      },
      "credentials": {
        "smtp": {
          "id": "0YIoKeISQNR2kxwO",
          "name": "SMTP Resent"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "979d0e82-42e8-450a-95b1-3c204ad61a50",
      "name": "Fallback E-Mail",
      "type": "n8n-nodes-base.emailSend",
      "disabled": true,
      "position": [
        -760,
        350
      ],
      "webhookId": "d76d2e82-b0a8-4e35-88f9-1815d4ce6c79",
      "parameters": {
        "text": "={{ $(\"Error Trigger\").item.json.execution.url }}\n\n{{ $(\"Error Trigger\").item.json.execution.lastNodeExecuted }}\n\n{{ $(\"Error Trigger\").item.json.execution.error.message }}\n{{ $(\"Error Trigger\").item.json.execution.error.stack }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "=Erro -  {{ $(\"Error Trigger\").item.json.workflow.name }}",
        "toEmail": "davimesquita@gmail.com",
        "fromEmail": "contato@ideias.casa",
        "emailFormat": "text"
      },
      "credentials": {
        "smtp": {
          "id": "UvWloRL7Jyqt8tm9",
          "name": "SMTP Contato"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "6c073c03-e00e-45b1-8f14-faa29fd58472",
      "name": "Push mobile notification",
      "type": "n8n-nodes-base.pushover",
      "disabled": true,
      "position": [
        -980,
        550
      ],
      "parameters": {
        "message": "={{ $(\"Error Trigger\").item.json.workflow.name }} - {{ $(\"Error Trigger\").item.json.execution.url }}\n\n{{ $(\"Error Trigger\").item.json.execution.lastNodeExecuted }}\n\n{{ $(\"Error Trigger\").item.json.execution.error.message }}\n{{ $(\"Error Trigger\").item.json.execution.error.stack }}",
        "userKey": "=u4RMqXQR9EFdeSQBfaL1riBy1Qd953",
        "additionalFields": {}
      },
      "credentials": {
        "pushoverApi": {
          "id": "ae8Jsj87n2hSWDbs",
          "name": "Pushover account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "4ca939e4-dcb1-40bd-b5eb-4cd00cb403fb",
      "name": "Truncate Log Database",
      "type": "n8n-nodes-base.postgres",
      "position": [
        -980,
        810
      ],
      "parameters": {
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "N8Err",
          "cachedResultName": "N8Err"
        },
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "p1gq6ljdsam3x1m",
          "cachedResultName": "p1gq6ljdsam3x1m"
        },
        "options": {},
        "operation": "deleteTable",
        "restartSequences": true
      },
      "credentials": {
        "postgres": {
          "id": "2VsRB7eDnG0FA3z2",
          "name": "Postgres Nocodb"
        }
      },
      "typeVersion": 2.6
    },
    {
      "id": "1eaf67ca-fb77-4b76-8ee3-ae65d4b79182",
      "name": "Sometimes... just cleanup",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -1200,
        810
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "01e5a7dd-41a2-43f1-bbf5-241e6791cf18",
      "name": "Call this Sample - Prepend to your error catcher",
      "type": "n8n-nodes-base.executeWorkflow",
      "disabled": true,
      "position": [
        -1200,
        450
      ],
      "parameters": {
        "options": {},
        "workflowId": {
          "__rl": true,
          "mode": "id",
          "value": ""
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "4386788d-5f10-468a-8a02-cff45a4a7ed5",
      "name": "See below to prepend this at your error handling",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "position": [
        -1200,
        -260
      ],
      "parameters": {
        "inputSource": "passthrough"
      },
      "typeVersion": 1.1
    },
    {
      "id": "d6aed974-4a36-4edd-809d-867a95d0f6ef",
      "name": "If there is no logs in 5 minutes",
      "type": "n8n-nodes-base.if",
      "position": [
        -760,
        -210
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "a17b915d-f581-4774-a78a-48bc386aebc9",
              "operator": {
                "type": "number",
                "operation": "lte"
              },
              "leftValue": "={{ $json.count }}",
              "rightValue": 0
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "3c49f611-f1a6-409a-a4c6-903dadb27165",
      "name": "CleanUp execution. See below if you will prepend this workflow",
      "type": "n8n-nodes-base.code",
      "position": [
        -540,
        -10
      ],
      "parameters": {
        "jsCode": "return [];"
      },
      "typeVersion": 2
    },
    {
      "id": "192443fc-c032-4815-acc7-c8cf6040cc34",
      "name": "Insert your error handling logic after this",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -540,
        -260
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "2f87907f-816f-4054-8517-bb713a203131",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1350,
        250
      ],
      "parameters": {
        "width": 840,
        "height": 460,
        "content": "# Error handling sample\n"
      },
      "typeVersion": 1
    },
    {
      "id": "b173898f-d1d8-4f83-b7b7-ba52cab7651e",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1610,
        630
      ],
      "parameters": {
        "width": 1140,
        "height": 340,
        "content": "# Database Cleanup: Useful in DEV, but DO NOT run in production"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {
    "Error Trigger": [
      {
        "json": {
          "workflow": {
            "id": "1",
            "name": "Example Workflow"
          },
          "execution": {
            "id": 231,
            "url": "https://work.ideias.casa/execution/workflow/1/231",
            "mode": "manual",
            "error": {
              "stack": "Stacktrace",
              "message": "Example Error Message"
            },
            "retryOf": "34",
            "lastNodeExecuted": "Node With Error"
          }
        }
      }
    ]
  },
  "settings": {
    "callerPolicy": "workflowsFromSameOwner",
    "executionOrder": "v1",
    "saveManualExecutions": false,
    "saveExecutionProgress": false,
    "saveDataErrorExecution": "all",
    "saveDataSuccessExecution": "none"
  },
  "versionId": "07c6795a-f906-4e22-a15a-4f1984e540a3",
  "connections": {
    "Insert Log": {
      "main": [
        [
          {
            "node": "CleanUp execution. See below if you will prepend this workflow",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Error Trigger": {
      "main": [
        [
          {
            "node": "Insert Log",
            "type": "main",
            "index": 0
          },
          {
            "node": "Count for 5 minutes",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Principal E-Mail": {
      "main": [
        [],
        [
          {
            "node": "Fallback E-Mail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Count for 5 minutes": {
      "main": [
        [
          {
            "node": "If there is no logs in 5 minutes",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sometimes... just cleanup": {
      "main": [
        [
          {
            "node": "Truncate Log Database",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If there is no logs in 5 minutes": {
      "main": [
        [
          {
            "node": "Insert your error handling logic after this",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "CleanUp execution. See below if you will prepend this workflow",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Call this Sample - Prepend to your error catcher": {
      "main": [
        [
          {
            "node": "Principal E-Mail",
            "type": "main",
            "index": 0
          },
          {
            "node": "Push mobile notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "See below to prepend this at your error handling": {
      "main": [
        [
          {
            "node": "Insert Log",
            "type": "main",
            "index": 0
          },
          {
            "node": "Count for 5 minutes",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "CleanUp execution. See below if you will prepend this workflow": {
      "main": [
        []
      ]
    }
  }
}