diff --git a/packages/core/src/WorkflowExecute.ts b/packages/core/src/WorkflowExecute.ts index 932596723d0a3..a87f98b25d29f 100644 --- a/packages/core/src/WorkflowExecute.ts +++ b/packages/core/src/WorkflowExecute.ts @@ -34,6 +34,7 @@ import type { WorkflowExecuteMode, CloseFunction, StartNodeData, + NodeExecutionHint, } from 'n8n-workflow'; import { LoggerProxy as Logger, @@ -41,6 +42,7 @@ import { NodeHelpers, NodeConnectionType, ApplicationError, + NodeExecutionOutput, } from 'n8n-workflow'; import get from 'lodash/get'; import * as NodeExecuteFunctions from './NodeExecuteFunctions'; @@ -807,6 +809,7 @@ export class WorkflowExecute { // Variables which hold temporary data for each node-execution let executionData: IExecuteData; let executionError: ExecutionBaseError | undefined; + let executionHints: NodeExecutionHint[] = []; let executionNode: INode; let nodeSuccessData: INodeExecutionData[][] | null | undefined; let runIndex: number; @@ -828,7 +831,7 @@ export class WorkflowExecute { let lastExecutionTry = ''; let closeFunction: Promise | undefined; - return new PCancelable(async (resolve, reject, onCancel) => { + return new PCancelable(async (resolve, _reject, onCancel) => { // Let as many nodes listen to the abort signal, without getting the MaxListenersExceededWarning setMaxListeners(Infinity, this.abortController.signal); @@ -896,6 +899,7 @@ export class WorkflowExecute { nodeSuccessData = null; executionError = undefined; + executionHints = []; executionData = this.runExecutionData.executionData!.nodeExecutionStack.shift() as IExecuteData; executionNode = executionData.node; @@ -1059,8 +1063,16 @@ export class WorkflowExecute { this.mode, this.abortController.signal, ); + nodeSuccessData = runNodeData.data; + if (nodeSuccessData instanceof NodeExecutionOutput) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + const hints: NodeExecutionHint[] = nodeSuccessData.getHints(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + executionHints.push(...hints); + } + if (nodeSuccessData && executionData.node.onError === 'continueErrorOutput') { // If errorOutput is activated check all the output items for error data. // If any is found, route them to the last output as that will be the @@ -1244,7 +1256,7 @@ export class WorkflowExecute { if (!inputData) { return; } - inputData.forEach((item, itemIndex) => { + inputData.forEach((_item, itemIndex) => { pairedItem.push({ item: itemIndex, input: inputIndex, @@ -1296,6 +1308,7 @@ export class WorkflowExecute { } taskData = { + hints: executionHints, startTime, executionTime: new Date().getTime() - startTime, source: !executionData.source ? [] : executionData.source.main, diff --git a/packages/core/test/WorkflowExecute.test.ts b/packages/core/test/WorkflowExecute.test.ts index 8ad953c6540c1..684aeaee559d5 100644 --- a/packages/core/test/WorkflowExecute.test.ts +++ b/packages/core/test/WorkflowExecute.test.ts @@ -1,5 +1,10 @@ import type { IRun, WorkflowTestData } from 'n8n-workflow'; -import { ApplicationError, createDeferredPromise, Workflow } from 'n8n-workflow'; +import { + ApplicationError, + createDeferredPromise, + NodeExecutionOutput, + Workflow, +} from 'n8n-workflow'; import { WorkflowExecute } from '@/WorkflowExecute'; import * as Helpers from './helpers'; @@ -192,4 +197,16 @@ describe('WorkflowExecute', () => { }); } }); + + describe('WorkflowExecute, NodeExecutionOutput type test', () => { + //TODO Add more tests here when execution hints are added to some node types + const nodeExecutionOutput = new NodeExecutionOutput( + [[{ json: { data: 123 } }]], + [{ message: 'TEXT HINT' }], + ); + + expect(nodeExecutionOutput).toBeInstanceOf(NodeExecutionOutput); + expect(nodeExecutionOutput[0][0].json.data).toEqual(123); + expect(nodeExecutionOutput.getHints()[0].message).toEqual('TEXT HINT'); + }); }); diff --git a/packages/editor-ui/src/components/RunData.vue b/packages/editor-ui/src/components/RunData.vue index 5adafcd71e944..2452726924145 100644 --- a/packages/editor-ui/src/components/RunData.vue +++ b/packages/editor-ui/src/components/RunData.vue @@ -152,6 +152,15 @@ + + + +