feat(10.2-01): add error and trace logging utility nodes

- Create Log Error code node with ring buffer write logic
- Create Log Trace code node with debug mode check and auto-disable
- Both nodes implement ring buffer (max 50 entries) with auto-rotation
- Log Error: accepts error data, truncates large fields (stack 500, raw 1000)
- Log Error: passes through input data with _errorLogged flag
- Log Trace: checks debug.enabled before logging, passes through unchanged
- Log Trace: auto-disables debug mode after 100 executions
- Both nodes positioned at utility area (2600, -200/-400)
- Nodes are standalone (no connections) - ready for Plan 02 wiring
- Node count: 170 -> 172 (+2 utility nodes)
This commit is contained in:
Lucas Berger
2026-02-08 12:47:32 -05:00
parent d1d13ca671
commit 030118efb3
+26
View File
@@ -4941,6 +4941,32 @@
"name": "Telegram account" "name": "Telegram account"
} }
} }
},
{
"parameters": {
"jsCode": "const staticData = $getWorkflowStaticData('global');\nconst input = $input.item.json;\n\n// Initialize if needed\nif (!staticData.errorLog) {\n staticData.errorLog = {\n debug: { enabled: false, executionCount: 0 },\n errors: { buffer: [], nextId: 1, count: 0, lastCleared: new Date().toISOString() },\n traces: { buffer: [], nextId: 1 }\n };\n}\n\nconst MAX_ERRORS = 50;\nconst errorEntry = {\n id: `err_${String(staticData.errorLog.errors.nextId).padStart(3, '0')}`,\n correlationId: input.correlationId || $execution.id,\n timestamp: new Date().toISOString(),\n executionId: $execution.id,\n workflow: input.workflow || 'main',\n node: input.node || 'unknown',\n operation: input.operation || 'unknown',\n userMessage: input.userMessage || input.errorMessage || 'Unknown error',\n error: {\n message: input.errorMessage || 'Unknown error',\n stack: (input.errorStack || '').substring(0, 500),\n httpCode: input.httpCode || null,\n rawResponse: (input.rawResponse || '').substring(0, 1000)\n },\n context: input.contextData || {}\n};\n\n// Ring buffer: push and rotate\nstaticData.errorLog.errors.buffer.push(errorEntry);\nif (staticData.errorLog.errors.buffer.length > MAX_ERRORS) {\n staticData.errorLog.errors.buffer.shift();\n}\nstaticData.errorLog.errors.nextId++;\nstaticData.errorLog.errors.count++;\n\n// Pass through all input data so downstream nodes still work\nreturn { json: { ...input, _errorLogged: true, _errorId: errorEntry.id } };"
},
"id": "code-log-error",
"name": "Log Error",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2600,
-200
]
},
{
"parameters": {
"jsCode": "const staticData = $getWorkflowStaticData('global');\nconst input = $input.item.json;\n\n// Initialize if needed\nif (!staticData.errorLog) {\n staticData.errorLog = {\n debug: { enabled: false, executionCount: 0 },\n errors: { buffer: [], nextId: 1, count: 0, lastCleared: new Date().toISOString() },\n traces: { buffer: [], nextId: 1 }\n };\n}\n\n// Check if debug mode is enabled\nif (!staticData.errorLog.debug.enabled) {\n // Debug mode off, pass through unchanged\n return { json: input };\n}\n\n// Increment execution count and check auto-disable threshold\nstaticData.errorLog.debug.executionCount++;\nif (staticData.errorLog.debug.executionCount >= 100) {\n staticData.errorLog.debug.enabled = false;\n // Note: Auto-disable happened, but we don't have a way to notify here\n // The /debug status command will show it's disabled\n}\n\nconst MAX_TRACES = 50;\nconst traceEntry = {\n id: `trace_${String(staticData.errorLog.traces.nextId).padStart(3, '0')}`,\n correlationId: input.correlationId || $execution.id,\n timestamp: new Date().toISOString(),\n executionId: $execution.id,\n event: input.event || 'unknown', // \"sub-workflow-call\" | \"callback-routing\"\n workflow: input.workflow || 'main',\n node: input.node || 'unknown',\n data: input.traceData || {}\n};\n\n// Ring buffer: push and rotate\nstaticData.errorLog.traces.buffer.push(traceEntry);\nif (staticData.errorLog.traces.buffer.length > MAX_TRACES) {\n staticData.errorLog.traces.buffer.shift();\n}\nstaticData.errorLog.traces.nextId++;\n\n// Pass through all input data unchanged\nreturn { json: { ...input, _traceLogged: true, _traceId: traceEntry.id } };"
},
"id": "code-log-trace",
"name": "Log Trace",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2600,
-400
]
} }
], ],
"connections": { "connections": {