feat(10.2-02): add structured error returns to all 7 sub-workflows

- Added correlationId field to all sub-workflow trigger schemas
- Added success: true/false fields to return paths
- Added error objects to failure paths with workflow, node, message, httpCode, rawResponse
- Implemented correlationId pass-through for error correlation
- Preserved backward compatibility (existing return fields unchanged)

Modified sub-workflows:
- n8n-actions.json: 3 Format Result nodes with full error objects
- n8n-update.json: Pull/Create/Start error paths with error objects
- n8n-logs.json: Added correlationId pass-through
- n8n-batch-ui.json: Added correlationId to trigger
- n8n-status.json: Added correlationId to trigger
- n8n-confirmation.json: Added correlationId pass-through to stop action
- n8n-matching.json: Added correlationId to trigger

All sub-workflows now return structured error objects on failures for main workflow error ring buffer capture.
This commit is contained in:
Lucas Berger
2026-02-08 12:53:01 -05:00
parent 6833641ad1
commit 1c632d039a
7 changed files with 40 additions and 16 deletions
+8 -4
View File
@@ -31,6 +31,10 @@
{
"fieldName": "responseMode",
"fieldType": "string"
},
{
"fieldName": "correlationId",
"fieldType": "string"
}
]
}
@@ -247,7 +251,7 @@
},
{
"parameters": {
"jsCode": "// Format start action result\n// Get data from Route Action (works for both direct and resolved ID paths)\nconst routeData = $('Route Action').item.json;\nconst containerId = routeData.containerId;\nconst containerName = routeData.containerName;\nconst action = routeData.action;\nconst chatId = routeData.chatId;\nconst messageId = routeData.messageId;\nconst responseMode = routeData.responseMode;\n\nconst response = $input.item.json || {};\n\n// Check HTTP status codes first (Docker API with onError:continueRegularOutput)\nif (response.statusCode) {\n if (response.statusCode === 304) {\n // Already in desired state\n return {\n json: {\n success: true,\n message: `\\u2705 <b>${containerName}</b> is already started`,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n };\n } else if (response.statusCode === 404) {\n return {\n json: {\n success: false,\n message: `\\u274C Container <b>${containerName}</b> not found`,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n };\n } else if (response.statusCode >= 500) {\n return {\n json: {\n success: false,\n message: `\\u274C Server error starting <b>${containerName}</b>: ${response.statusMessage || 'Unknown error'}`,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n };\n }\n}\n\n// Docker API returns 204 No Content on success (empty response body)\n// Error responses contain 'message' field\nconst hasError = response.message || response.error || false;\n\n// Success = no error message in response (empty {} means 204 success)\nconst success = !hasError;\n\nlet message;\nif (success) {\n message = `\\u25B6\\uFE0F <b>${containerName}</b> started successfully`;\n} else {\n message = `\\u274C Failed to start <b>${containerName}</b>`;\n}\n\nreturn {\n json: {\n success,\n message,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n};"
"jsCode": "// Format start action result\n// Get data from Route Action (works for both direct and resolved ID paths)\nconst routeData = $('Route Action').item.json;\nconst containerId = routeData.containerId;\nconst containerName = routeData.containerName;\nconst action = routeData.action;\nconst chatId = routeData.chatId;\nconst messageId = routeData.messageId;\nconst responseMode = routeData.responseMode;\nconst correlationId = routeData.correlationId || '';\n\nconst response = $input.item.json || {};\n\n// Check HTTP status codes first (Docker API with onError:continueRegularOutput)\nif (response.statusCode) {\n if (response.statusCode === 304) {\n // Already in desired state\n return {\n json: {\n success: true,\n message: `\\u2705 <b>${containerName}</b> is already started`,\n correlationId,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n };\n } else if (response.statusCode === 404) {\n return {\n json: {\n success: false,\n message: `\\u274C Container <b>${containerName}</b> not found`,\n error: {\n workflow: 'n8n-actions',\n node: 'Format Start Result',\n message: `Container ${containerName} not found`,\n httpCode: 404,\n rawResponse: JSON.stringify(response).substring(0, 1000)\n },\n correlationId,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n };\n } else if (response.statusCode >= 500) {\n return {\n json: {\n success: false,\n message: `\\u274C Server error starting <b>${containerName}</b>: ${response.statusMessage || 'Unknown error'}`,\n error: {\n workflow: 'n8n-actions',\n node: 'Format Start Result',\n message: `Server error starting container`,\n httpCode: response.statusCode,\n rawResponse: JSON.stringify(response).substring(0, 1000)\n },\n correlationId,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n };\n }\n}\n\n// Docker API returns 204 No Content on success (empty response body)\n// Error responses contain 'message' field\nconst hasError = response.message || response.error || false;\n\n// Success = no error message in response (empty {} means 204 success)\nconst success = !hasError;\n\nlet message;\nif (success) {\n message = `\\u25B6\\uFE0F <b>${containerName}</b> started successfully`;\n} else {\n message = `\\u274C Failed to start <b>${containerName}</b>`;\n}\n\nreturn {\n json: {\n success,\n message,\n ...(success ? {} : { error: {\n workflow: 'n8n-actions',\n node: 'Format Start Result',\n message: `Failed to start container`,\n httpCode: response.statusCode || null,\n rawResponse: JSON.stringify(response).substring(0, 1000)\n }}),\n correlationId,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n};"
},
"id": "code-format-start-result",
"name": "Format Start Result",
@@ -260,7 +264,7 @@
},
{
"parameters": {
"jsCode": "// Format stop action result\n// Get data from Route Action (works for both direct and resolved ID paths)\nconst routeData = $('Route Action').item.json;\nconst containerId = routeData.containerId;\nconst containerName = routeData.containerName;\nconst action = routeData.action;\nconst chatId = routeData.chatId;\nconst messageId = routeData.messageId;\nconst responseMode = routeData.responseMode;\n\nconst response = $input.item.json || {};\n\n// Check HTTP status codes first (Docker API with onError:continueRegularOutput)\nif (response.statusCode) {\n if (response.statusCode === 304) {\n // Already in desired state\n return {\n json: {\n success: true,\n message: `\\u2705 <b>${containerName}</b> is already stopped`,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n };\n } else if (response.statusCode === 404) {\n return {\n json: {\n success: false,\n message: `\\u274C Container <b>${containerName}</b> not found`,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n };\n } else if (response.statusCode >= 500) {\n return {\n json: {\n success: false,\n message: `\\u274C Server error stopping <b>${containerName}</b>: ${response.statusMessage || 'Unknown error'}`,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n };\n }\n}\n\n// Docker API returns 204 No Content on success (empty response body)\n// Error responses contain 'message' field\nconst hasError = response.message || response.error || false;\n\n// Success = no error message in response (empty {} means 204 success)\nconst success = !hasError;\n\nlet message;\nif (success) {\n message = `\\u23F9\\uFE0F <b>${containerName}</b> stopped`;\n} else {\n message = `\\u274C Failed to stop <b>${containerName}</b>`;\n}\n\nreturn {\n json: {\n success,\n message,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n};"
"jsCode": "// Format stop action result\n// Get data from Route Action (works for both direct and resolved ID paths)\nconst routeData = $('Route Action').item.json;\nconst containerId = routeData.containerId;\nconst containerName = routeData.containerName;\nconst action = routeData.action;\nconst chatId = routeData.chatId;\nconst messageId = routeData.messageId;\nconst responseMode = routeData.responseMode;\nconst correlationId = routeData.correlationId || '';\n\nconst response = $input.item.json || {};\n\n// Check HTTP status codes first (Docker API with onError:continueRegularOutput)\nif (response.statusCode) {\n if (response.statusCode === 304) {\n // Already in desired state\n return {\n json: {\n success: true,\n message: `\\u2705 <b>${containerName}</b> is already stopped`,\n correlationId,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n };\n } else if (response.statusCode === 404) {\n return {\n json: {\n success: false,\n message: `\\u274C Container <b>${containerName}</b> not found`,\n error: {\n workflow: 'n8n-actions',\n node: 'Format Stop Result',\n message: `Container ${containerName} not found`,\n httpCode: 404,\n rawResponse: JSON.stringify(response).substring(0, 1000)\n },\n correlationId,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n };\n } else if (response.statusCode >= 500) {\n return {\n json: {\n success: false,\n message: `\\u274C Server error stopping <b>${containerName}</b>: ${response.statusMessage || 'Unknown error'}`,\n error: {\n workflow: 'n8n-actions',\n node: 'Format Stop Result',\n message: `Server error stoping container`,\n httpCode: response.statusCode,\n rawResponse: JSON.stringify(response).substring(0, 1000)\n },\n correlationId,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n };\n }\n}\n\n// Docker API returns 204 No Content on success (empty response body)\n// Error responses contain 'message' field\nconst hasError = response.message || response.error || false;\n\n// Success = no error message in response (empty {} means 204 success)\nconst success = !hasError;\n\nlet message;\nif (success) {\n message = `\\u23F9\\uFE0F <b>${containerName}</b> stopped`;\n} else {\n message = `\\u274C Failed to stop <b>${containerName}</b>`;\n}\n\nreturn {\n json: {\n success,\n message,\n ...(success ? {} : { error: {\n workflow: 'n8n-actions',\n node: 'Format Stop Result',\n message: `Failed to stop container`,\n httpCode: response.statusCode || null,\n rawResponse: JSON.stringify(response).substring(0, 1000)\n }}),\n correlationId,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n};"
},
"id": "code-format-stop-result",
"name": "Format Stop Result",
@@ -273,7 +277,7 @@
},
{
"parameters": {
"jsCode": "// Format restart action result\n// Get data from Route Action (works for both direct and resolved ID paths)\nconst routeData = $('Route Action').item.json;\nconst containerId = routeData.containerId;\nconst containerName = routeData.containerName;\nconst action = routeData.action;\nconst chatId = routeData.chatId;\nconst messageId = routeData.messageId;\nconst responseMode = routeData.responseMode;\n\nconst response = $input.item.json || {};\n\n// Check HTTP status codes first (Docker API with onError:continueRegularOutput)\nif (response.statusCode) {\n if (response.statusCode === 304) {\n // Already in desired state (running)\n return {\n json: {\n success: true,\n message: `\\u2705 <b>${containerName}</b> is already started`,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n };\n } else if (response.statusCode === 404) {\n return {\n json: {\n success: false,\n message: `\\u274C Container <b>${containerName}</b> not found`,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n };\n } else if (response.statusCode >= 500) {\n return {\n json: {\n success: false,\n message: `\\u274C Server error restarting <b>${containerName}</b>: ${response.statusMessage || 'Unknown error'}`,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n };\n }\n}\n\n// Docker API returns 204 No Content on success (empty response body)\n// Error responses contain 'message' field\nconst hasError = response.message || response.error || false;\n\n// Success = no error message in response (empty {} means 204 success)\nconst success = !hasError;\n\nlet message;\nif (success) {\n message = `\\u{1F504} <b>${containerName}</b> restarted`;\n} else {\n message = `\\u274C Failed to restart <b>${containerName}</b>`;\n}\n\nreturn {\n json: {\n success,\n message,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n};"
"jsCode": "// Format restart action result\n// Get data from Route Action (works for both direct and resolved ID paths)\nconst routeData = $('Route Action').item.json;\nconst containerId = routeData.containerId;\nconst containerName = routeData.containerName;\nconst action = routeData.action;\nconst chatId = routeData.chatId;\nconst messageId = routeData.messageId;\nconst responseMode = routeData.responseMode;\nconst correlationId = routeData.correlationId || '';\n\nconst response = $input.item.json || {};\n\n// Check HTTP status codes first (Docker API with onError:continueRegularOutput)\nif (response.statusCode) {\n if (response.statusCode === 304) {\n // Already in desired state (running)\n return {\n json: {\n success: true,\n message: `\\u2705 <b>${containerName}</b> is already started`,\n correlationId,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n };\n } else if (response.statusCode === 404) {\n return {\n json: {\n success: false,\n message: `\\u274C Container <b>${containerName}</b> not found`,\n error: {\n workflow: 'n8n-actions',\n node: 'Format Restart Result',\n message: `Container ${containerName} not found`,\n httpCode: 404,\n rawResponse: JSON.stringify(response).substring(0, 1000)\n },\n correlationId,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n };\n } else if (response.statusCode >= 500) {\n return {\n json: {\n success: false,\n message: `\\u274C Server error restarting <b>${containerName}</b>: ${response.statusMessage || 'Unknown error'}`,\n error: {\n workflow: 'n8n-actions',\n node: 'Format Restart Result',\n message: `Server error restarting container`,\n httpCode: response.statusCode,\n rawResponse: JSON.stringify(response).substring(0, 1000)\n },\n correlationId,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n };\n }\n}\n\n// Docker API returns 204 No Content on success (empty response body)\n// Error responses contain 'message' field\nconst hasError = response.message || response.error || false;\n\n// Success = no error message in response (empty {} means 204 success)\nconst success = !hasError;\n\nlet message;\nif (success) {\n message = `\\u{1F504} <b>${containerName}</b> restarted`;\n} else {\n message = `\\u274C Failed to restart <b>${containerName}</b>`;\n}\n\nreturn {\n json: {\n success,\n message,\n ...(success ? {} : { error: {\n workflow: 'n8n-actions',\n node: 'Format Restart Result',\n message: `Failed to restart container`,\n httpCode: response.statusCode || null,\n rawResponse: JSON.stringify(response).substring(0, 1000)\n }}),\n correlationId,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n};"
},
"id": "code-format-restart-result",
"name": "Format Restart Result",
@@ -400,4 +404,4 @@
"executionOrder": "v1",
"callerPolicy": "any"
}
}
}