From 20cdcb5839cfe305ec1ef579a42c9a53c6615bcb Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Fri, 1 Apr 2022 12:22:19 +0200 Subject: [PATCH 1/2] :bug: Fix issue that IMAP node can crash n8n --- packages/cli/src/ActiveWorkflowRunner.ts | 9 +++++++++ packages/core/src/NodeExecuteFunctions.ts | 3 +++ .../nodes/EmailReadImap/EmailReadImap.node.ts | 20 ++++++++++++------- packages/workflow/src/Interfaces.ts | 1 + packages/workflow/src/Workflow.ts | 16 ++++++++++++++- 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/packages/cli/src/ActiveWorkflowRunner.ts b/packages/cli/src/ActiveWorkflowRunner.ts index bc24be401952d..f14fb23ab95a9 100644 --- a/packages/cli/src/ActiveWorkflowRunner.ts +++ b/packages/cli/src/ActiveWorkflowRunner.ts @@ -682,6 +682,15 @@ export class ActiveWorkflowRunner { (error) => console.error(error), ); }; + returnFunctions.emitError = async (error: Error): Promise => { + await this.activeWorkflows?.remove(workflowData.id.toString()); + this.activationErrors[workflowData.id.toString()] = { + time: new Date().getTime(), + error: { + message: error.message, + }, + }; + }; return returnFunctions; }; } diff --git a/packages/core/src/NodeExecuteFunctions.ts b/packages/core/src/NodeExecuteFunctions.ts index 1d54de9a114a8..02c0723438e87 100644 --- a/packages/core/src/NodeExecuteFunctions.ts +++ b/packages/core/src/NodeExecuteFunctions.ts @@ -1750,6 +1750,9 @@ export function getExecuteTriggerFunctions( emit: (data: INodeExecutionData[][]): void => { throw new Error('Overwrite NodeExecuteFunctions.getExecuteTriggerFunctions.emit function!'); }, + emitError: (error: Error): void => { + throw new Error('Overwrite NodeExecuteFunctions.getExecuteTriggerFunctions.emit function!'); + }, async getCredentials(type: string): Promise { return getCredentials(workflow, node, type, additionalData, mode); }, diff --git a/packages/nodes-base/nodes/EmailReadImap/EmailReadImap.node.ts b/packages/nodes-base/nodes/EmailReadImap/EmailReadImap.node.ts index 3cd39dfb9bfc0..87696678f3e9e 100644 --- a/packages/nodes-base/nodes/EmailReadImap/EmailReadImap.node.ts +++ b/packages/nodes-base/nodes/EmailReadImap/EmailReadImap.node.ts @@ -1,13 +1,15 @@ import { ITriggerFunctions } from 'n8n-core'; import { + createDeferredPromise, IBinaryData, IBinaryKeyData, IDataObject, + IDeferredPromise, INodeExecutionData, INodeType, INodeTypeDescription, ITriggerResponse, - LoggerProxy, + LoggerProxy as Logger, NodeOperationError, } from 'n8n-workflow'; @@ -25,10 +27,6 @@ import { import * as lodash from 'lodash'; -import { - LoggerProxy as Logger -} from 'n8n-workflow'; - export class EmailReadImap implements INodeType { description: INodeTypeDescription = { displayName: 'EmailReadImap', @@ -377,6 +375,8 @@ export class EmailReadImap implements INodeType { return newEmails; }; + const returnedPromise: IDeferredPromise | undefined = await createDeferredPromise(); + const establishConnection = (): Promise => { let searchCriteria = [ @@ -425,7 +425,11 @@ export class EmailReadImap implements INodeType { } } catch (error) { Logger.error('Email Read Imap node encountered an error fetching new emails', { error }); - throw error; + // Wait with resolving till the returnedPromise got resolved, else n8n will be unhappy + // if it receives an error before the workflow got activated + returnedPromise.promise().then(() => { + this.emitError(error as Error); + }) } } }, @@ -475,10 +479,12 @@ export class EmailReadImap implements INodeType { await connection.end(); } + // Resolve returned-promise so that waiting errors can be emitted + returnedPromise.resolve(); + return { closeFunction, }; - } } diff --git a/packages/workflow/src/Interfaces.ts b/packages/workflow/src/Interfaces.ts index 058b471c43375..5a0fba9d00b0e 100644 --- a/packages/workflow/src/Interfaces.ts +++ b/packages/workflow/src/Interfaces.ts @@ -683,6 +683,7 @@ export interface ITriggerFunctions { data: INodeExecutionData[][], responsePromise?: IDeferredPromise, ): void; + emitError(error: Error, responsePromise?: IDeferredPromise): void; getCredentials(type: string): Promise; getMode(): WorkflowExecuteMode; getActivationMode(): WorkflowActivateMode; diff --git a/packages/workflow/src/Workflow.ts b/packages/workflow/src/Workflow.ts index db696ab9fd51d..adcee421bcf37 100644 --- a/packages/workflow/src/Workflow.ts +++ b/packages/workflow/src/Workflow.ts @@ -949,7 +949,7 @@ export class Workflow { const triggerResponse = await nodeType.trigger.call(triggerFunctions); // Add the manual trigger response which resolves when the first time data got emitted - triggerResponse!.manualTriggerResponse = new Promise((resolve) => { + triggerResponse!.manualTriggerResponse = new Promise((resolve, reject) => { triggerFunctions.emit = ( (resolveEmit) => ( @@ -967,6 +967,20 @@ export class Workflow { resolveEmit(data); } )(resolve); + triggerFunctions.emitError = ( + (rejectEmit) => + (error: Error, responsePromise?: IDeferredPromise) => { + additionalData.hooks!.hookFunctions.sendResponse = [ + async (): Promise => { + if (responsePromise) { + responsePromise.reject(error); + } + }, + ]; + + rejectEmit(error); + } + )(reject); }); return triggerResponse; From 350dd0ff550332e21a466b8cc8cea845180a1d67 Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Sat, 2 Apr 2022 08:52:25 +0200 Subject: [PATCH 2/2] :shirt: Fix lint issue --- packages/nodes-base/nodes/EmailReadImap/EmailReadImap.node.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nodes-base/nodes/EmailReadImap/EmailReadImap.node.ts b/packages/nodes-base/nodes/EmailReadImap/EmailReadImap.node.ts index 87696678f3e9e..2f1104d3e21ab 100644 --- a/packages/nodes-base/nodes/EmailReadImap/EmailReadImap.node.ts +++ b/packages/nodes-base/nodes/EmailReadImap/EmailReadImap.node.ts @@ -429,7 +429,7 @@ export class EmailReadImap implements INodeType { // if it receives an error before the workflow got activated returnedPromise.promise().then(() => { this.emitError(error as Error); - }) + }); } } },