From 6e70f16c4b23e6e1c111a00db33ec664e879bbce Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Sat, 23 Nov 2019 21:57:50 +0100 Subject: [PATCH] :zap: Log and display also errors that occur in webhook function --- packages/cli/src/WebhookHelpers.ts | 67 ++++++++++++++++++++++++------ packages/workflow/src/Workflow.ts | 9 ++++ 2 files changed, 63 insertions(+), 13 deletions(-) diff --git a/packages/cli/src/WebhookHelpers.ts b/packages/cli/src/WebhookHelpers.ts index 8ff9802bed..77ef8087be 100644 --- a/packages/cli/src/WebhookHelpers.ts +++ b/packages/cli/src/WebhookHelpers.ts @@ -28,6 +28,7 @@ import { IRunExecutionData, ITaskData, IWebhookData, + IWebhookResponseData, IWorkflowExecuteAdditionalData, NodeHelpers, Workflow, @@ -124,7 +125,7 @@ export function getWorkflowWebhooks(workflow: Workflow, additionalData: IWorkflo // If the mode is not known we error. Is probably best like that instead of using // the default that people know as early as possible (probably already testing phase) // that something does not resolve properly. - const errorMessage = `The response mode ${responseMode} is not valid!.`; + const errorMessage = `The response mode ${responseMode} is not valid!`; responseCallback(new Error(errorMessage), {}); throw new ResponseHelper.ResponseError(errorMessage, 500, 500); } @@ -138,12 +139,41 @@ export function getWorkflowWebhooks(workflow: Workflow, additionalData: IWorkflo additionalData.httpResponse = res; let didSendResponse = false; + let runExecutionDataMerge = {}; try { // Run the webhook function to see what should be returned and if // the workflow should be executed or not - const webhookResultData = await webhookData.workflow.runWebhook(webhookData, workflowStartNode, additionalData, NodeExecuteFunctions, executionMode); + let webhookResultData: IWebhookResponseData; - if (webhookResultData.noWebhookResponse === true) { + try { + webhookResultData = await webhookData.workflow.runWebhook(webhookData, workflowStartNode, additionalData, NodeExecuteFunctions, executionMode); + } catch (e) { + // Send error response to webhook caller + const errorMessage = 'Workflow Webhook Error: Workflow could not be started!'; + responseCallback(new Error(errorMessage), {}); + didSendResponse = true; + + // Add error to execution data that it can be logged and send to Editor-UI + runExecutionDataMerge = { + resultData: { + runData: {}, + lastNodeExecuted: workflowStartNode.name, + error: { + message: e.message, + stack: e.stack, + }, + }, + }; + + webhookResultData = { + noWebhookResponse: true, + // Add empty data that it at least tries to "execute" the webhook + // which then so gets the chance to throw the error. + workflowData: [[{json: {}}]], + }; + } + + if (webhookResultData.noWebhookResponse === true && didSendResponse === false) { // The response got already send responseCallback(null, { noWebhookResponse: true, @@ -155,18 +185,24 @@ export function getWorkflowWebhooks(workflow: Workflow, additionalData: IWorkflo // Workflow should not run if (webhookResultData.webhookResponse !== undefined) { // Data to respond with is given - responseCallback(null, { - data: webhookResultData.webhookResponse, - responseCode, - }); + if (didSendResponse === false) { + responseCallback(null, { + data: webhookResultData.webhookResponse, + responseCode, + }); + didSendResponse = true; + } } else { // Send default response - responseCallback(null, { - data: { - message: 'Webhook call got received.', - }, - responseCode, - }); + if (didSendResponse === false) { + responseCallback(null, { + data: { + message: 'Webhook call got received.', + }, + responseCode, + }); + didSendResponse = true; + } } return; } @@ -217,6 +253,11 @@ export function getWorkflowWebhooks(workflow: Workflow, additionalData: IWorkflo }, }; + if (Object.keys(runExecutionDataMerge).length !== 0) { + // If data to merge got defined add it to the execution data + Object.assign(runExecutionData, runExecutionDataMerge); + } + const runData: IWorkflowExecutionDataProcess = { credentials, executionMode, diff --git a/packages/workflow/src/Workflow.ts b/packages/workflow/src/Workflow.ts index fd10723256..9efaaa67ec 100644 --- a/packages/workflow/src/Workflow.ts +++ b/packages/workflow/src/Workflow.ts @@ -1061,6 +1061,15 @@ export class Workflow { return null; } + if (runExecutionData.resultData.lastNodeExecuted === node.name && runExecutionData.resultData.error !== undefined) { + // The node did already fail. So throw an error here that it displays and logs it correctly. + // Does get used by webhook and trigger nodes in case they throw an error that it is possible + // to log the error and display in Editor-UI. + const error = new Error(runExecutionData.resultData.error.message); + error.stack = runExecutionData.resultData.error.stack; + throw error; + } + if (nodeType.executeSingle) { const returnPromises: Array> = [];