Log and display also errors that occur in webhook function

This commit is contained in:
Jan Oberhauser 2019-11-23 21:57:50 +01:00
parent 60241d3163
commit 6e70f16c4b
2 changed files with 63 additions and 13 deletions

View file

@ -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,

View file

@ -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<Promise<INodeExecutionData>> = [];