{ "name": "Genome: on-error", "nodes": [ { "parameters": {}, "id": "f715ed51-95e6-475f-8aa5-d0df531cc7cf", "name": "Error Trigger", "type": "n8n-nodes-base.errorTrigger", "typeVersion": 1, "position": [ 688, -32 ] }, { "parameters": { "mode": "runOnceForEachItem", "jsCode": "// Global error handler: set this workflow as the \"Error Workflow\" in each genome workflow's\n// Settings. Catches ANY node failure (SSH down, Forgejo 4xx/5xx, etc.) and notifies once.\n// Run Once for Each Item: $json is the error trigger payload.\nconst e = $json.execution || {};\nconst w = $json.workflow || {};\n\n// Safely extract error message from various shapes\nconst rawMsg = (e.error && (e.error.message || e.error.description)) || 'errore sconosciuto';\nconst msg = String(rawMsg).trim();\n\nconst lastNode = e.lastNodeExecuted ? ` (nodo: ${e.lastNodeExecuted})` : '';\nconst workflowName = w.name || 'n8n';\nconst executionUrl = e.url || '';\n\n// Escape markdown to avoid breaking the notification body\nconst msgEsc = msg.replace(/`/g, '\\`').replace(/\\n/g, '\\n');\n\nreturn {\n topic: 'genome-ingest',\n title: `Workflow KO · ${workflowName}`,\n priority: 'high',\n tags: 'rotating_light',\n click: executionUrl,\n actions: executionUrl ? `view, Apri l'esecuzione, ${executionUrl}` : '',\n body: `**${workflowName}** è fallito${lastNode}.\\n\\n${msgEsc}`\n};" }, "id": "dd39bc0f-918a-4645-8f04-540ac9089311", "name": "Build ntfy", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 928, -32 ] }, { "parameters": { "method": "POST", "url": "=http://ntfy/{{ $json.topic }}", "authentication": "genericCredentialType", "genericAuthType": "httpBearerAuth", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "Title", "value": "={{ $json.title }}" }, { "name": "Priority", "value": "={{ $json.priority }}" }, { "name": "Tags", "value": "={{ $json.tags }}" }, { "name": "Click", "value": "={{ $json.click }}" }, { "name": "Actions", "value": "={{ $json.actions }}" }, { "name": "Markdown", "value": "yes" } ] }, "sendBody": true, "contentType": "raw", "rawContentType": "Raw / Text", "body": "={{ $json.body }}", "options": { "timeout": 15000 } }, "id": "a9ee90f3-d7fe-445d-96af-12caef46473f", "name": "ntfy: send", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.4, "position": [ 1152, -32 ], "credentials": { "httpHeaderAuth": { "id": "TBPXSWOF63k9mvm8", "name": "ntfy-token" }, "httpBearerAuth": { "id": "nCv4CUN7Ef086Ewj", "name": "Bearer Auth account" } } } ], "pinData": {}, "connections": { "Error Trigger": { "main": [ [ { "node": "Build ntfy", "type": "main", "index": 0 } ] ] }, "Build ntfy": { "main": [ [ { "node": "ntfy: send", "type": "main", "index": 0 } ] ] } }, "active": true, "settings": { "executionOrder": "v1", "binaryMode": "separate" }, "versionId": "036161c9-c934-474e-9b4f-634259f2a866", "meta": { "instanceId": "96b2f0ec76a4400bbd481c617b24b3b87024cc7a913efacccaf9fc85722e7417" }, "id": "7Vws3gCX3QnjM3oD", "tags": [] }