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, IRunExecutionData,
ITaskData, ITaskData,
IWebhookData, IWebhookData,
IWebhookResponseData,
IWorkflowExecuteAdditionalData, IWorkflowExecuteAdditionalData,
NodeHelpers, NodeHelpers,
Workflow, 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 // 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) // the default that people know as early as possible (probably already testing phase)
// that something does not resolve properly. // 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), {}); responseCallback(new Error(errorMessage), {});
throw new ResponseHelper.ResponseError(errorMessage, 500, 500); throw new ResponseHelper.ResponseError(errorMessage, 500, 500);
} }
@ -138,12 +139,41 @@ export function getWorkflowWebhooks(workflow: Workflow, additionalData: IWorkflo
additionalData.httpResponse = res; additionalData.httpResponse = res;
let didSendResponse = false; let didSendResponse = false;
let runExecutionDataMerge = {};
try { try {
// Run the webhook function to see what should be returned and if // Run the webhook function to see what should be returned and if
// the workflow should be executed or not // 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 // The response got already send
responseCallback(null, { responseCallback(null, {
noWebhookResponse: true, noWebhookResponse: true,
@ -155,18 +185,24 @@ export function getWorkflowWebhooks(workflow: Workflow, additionalData: IWorkflo
// Workflow should not run // Workflow should not run
if (webhookResultData.webhookResponse !== undefined) { if (webhookResultData.webhookResponse !== undefined) {
// Data to respond with is given // Data to respond with is given
responseCallback(null, { if (didSendResponse === false) {
data: webhookResultData.webhookResponse, responseCallback(null, {
responseCode, data: webhookResultData.webhookResponse,
}); responseCode,
});
didSendResponse = true;
}
} else { } else {
// Send default response // Send default response
responseCallback(null, { if (didSendResponse === false) {
data: { responseCallback(null, {
message: 'Webhook call got received.', data: {
}, message: 'Webhook call got received.',
responseCode, },
}); responseCode,
});
didSendResponse = true;
}
} }
return; 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 = { const runData: IWorkflowExecutionDataProcess = {
credentials, credentials,
executionMode, executionMode,

View file

@ -1061,6 +1061,15 @@ export class Workflow {
return null; 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) { if (nodeType.executeSingle) {
const returnPromises: Array<Promise<INodeExecutionData>> = []; const returnPromises: Array<Promise<INodeExecutionData>> = [];