n8n-core 1.107.1 → 1.109.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/binary-data/index.d.ts +1 -1
- package/dist/binary-data/index.js +0 -1
- package/dist/binary-data/index.js.map +1 -1
- package/dist/build.tsbuildinfo +1 -1
- package/dist/errors/error-reporter.d.ts +2 -1
- package/dist/errors/error-reporter.js +5 -2
- package/dist/errors/error-reporter.js.map +1 -1
- package/dist/execution-engine/index.d.ts +6 -1
- package/dist/execution-engine/index.js +0 -1
- package/dist/execution-engine/index.js.map +1 -1
- package/dist/execution-engine/node-execution-context/execute-context.js +2 -0
- package/dist/execution-engine/node-execution-context/execute-context.js.map +1 -1
- package/dist/execution-engine/node-execution-context/load-options-context.js +2 -0
- package/dist/execution-engine/node-execution-context/load-options-context.js.map +1 -1
- package/dist/execution-engine/node-execution-context/local-load-options-context.js +1 -3
- package/dist/execution-engine/node-execution-context/local-load-options-context.js.map +1 -1
- package/dist/execution-engine/node-execution-context/supply-data-context.js +2 -0
- package/dist/execution-engine/node-execution-context/supply-data-context.js.map +1 -1
- package/dist/execution-engine/node-execution-context/utils/data-store-helper-functions.d.ts +2 -0
- package/dist/execution-engine/node-execution-context/utils/data-store-helper-functions.js +13 -0
- package/dist/execution-engine/node-execution-context/utils/data-store-helper-functions.js.map +1 -0
- package/dist/execution-engine/node-execution-context/utils/file-system-helper-functions.js +8 -8
- package/dist/execution-engine/node-execution-context/utils/file-system-helper-functions.js.map +1 -1
- package/dist/execution-engine/workflow-execute.d.ts +14 -1
- package/dist/execution-engine/workflow-execute.js +169 -127
- package/dist/execution-engine/workflow-execute.js.map +1 -1
- package/dist/html-sandbox.d.ts +2 -6
- package/dist/html-sandbox.js +7 -100
- package/dist/html-sandbox.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/package.json +9 -9
|
@@ -119,7 +119,7 @@ class WorkflowExecute {
|
|
|
119
119
|
};
|
|
120
120
|
return this.processRunExecutionData(workflow);
|
|
121
121
|
}
|
|
122
|
-
|
|
122
|
+
isLegacyExecutionOrder(workflow) {
|
|
123
123
|
return workflow.settings.executionOrder !== 'v1';
|
|
124
124
|
}
|
|
125
125
|
runPartialWorkflow(workflow, runData, startNodes, destinationNode, pinData) {
|
|
@@ -460,14 +460,13 @@ class WorkflowExecute {
|
|
|
460
460
|
if (!nodeWasWaiting) {
|
|
461
461
|
const checkOutputNodes = [];
|
|
462
462
|
for (const outputIndexParent in workflow.connectionsBySourceNode[parentNodeName].main) {
|
|
463
|
-
if (!workflow.connectionsBySourceNode[parentNodeName].main
|
|
463
|
+
if (!Object.hasOwn(workflow.connectionsBySourceNode[parentNodeName].main, outputIndexParent)) {
|
|
464
464
|
continue;
|
|
465
465
|
}
|
|
466
466
|
for (const connectionDataCheck of workflow.connectionsBySourceNode[parentNodeName].main[outputIndexParent] ?? []) {
|
|
467
467
|
checkOutputNodes.push(connectionDataCheck.node);
|
|
468
468
|
}
|
|
469
469
|
}
|
|
470
|
-
const forceInputNodeExecution = this.forceInputNodeExecution(workflow);
|
|
471
470
|
for (let inputIndex = 0; inputIndex < workflow.connectionsByDestinationNode[connectionData.node].main.length; inputIndex++) {
|
|
472
471
|
for (const inputData of workflow.connectionsByDestinationNode[connectionData.node].main[inputIndex] ?? []) {
|
|
473
472
|
if (inputData.node === parentNodeName) {
|
|
@@ -485,7 +484,7 @@ class WorkflowExecute {
|
|
|
485
484
|
if (this.runExecutionData.resultData.runData[inputData.node] !== undefined) {
|
|
486
485
|
continue;
|
|
487
486
|
}
|
|
488
|
-
if (!
|
|
487
|
+
if (!this.isLegacyExecutionOrder(workflow)) {
|
|
489
488
|
continue;
|
|
490
489
|
}
|
|
491
490
|
const parentNodes = workflow.getParentNodes(inputData.node, n8n_workflow_1.NodeConnectionTypes.Main, -1);
|
|
@@ -644,28 +643,23 @@ class WorkflowExecute {
|
|
|
644
643
|
const customOperation = customOperations[resource][operation];
|
|
645
644
|
return customOperation;
|
|
646
645
|
}
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
if (inputData.hasOwnProperty('main') && inputData.main.length > 0) {
|
|
652
|
-
if (inputData.main[0] === null) {
|
|
653
|
-
return { data: undefined };
|
|
654
|
-
}
|
|
655
|
-
return { data: [inputData.main[0]] };
|
|
646
|
+
handleDisabledNode(inputData) {
|
|
647
|
+
if (Object.hasOwn(inputData, 'main') && inputData.main.length > 0) {
|
|
648
|
+
if (inputData.main[0] === null) {
|
|
649
|
+
return { data: undefined };
|
|
656
650
|
}
|
|
657
|
-
return { data:
|
|
651
|
+
return { data: [inputData.main[0]] };
|
|
658
652
|
}
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
let connectionInputData = [];
|
|
653
|
+
return { data: undefined };
|
|
654
|
+
}
|
|
655
|
+
prepareConnectionInputData(workflow, nodeType, customOperation, inputData) {
|
|
663
656
|
if (nodeType.execute ||
|
|
664
657
|
customOperation ||
|
|
665
658
|
(!nodeType.poll && !nodeType.trigger && !nodeType.webhook)) {
|
|
666
|
-
if (inputData.main?.length
|
|
667
|
-
|
|
659
|
+
if (!inputData.main?.length) {
|
|
660
|
+
return null;
|
|
668
661
|
}
|
|
662
|
+
let connectionInputData = inputData.main[0];
|
|
669
663
|
const forceInputNodeExecution = workflow.settings.executionOrder !== 'v1';
|
|
670
664
|
if (!forceInputNodeExecution) {
|
|
671
665
|
for (const mainData of inputData.main) {
|
|
@@ -675,10 +669,14 @@ class WorkflowExecute {
|
|
|
675
669
|
}
|
|
676
670
|
}
|
|
677
671
|
}
|
|
678
|
-
if (connectionInputData.length === 0) {
|
|
679
|
-
return
|
|
672
|
+
if (!connectionInputData || connectionInputData.length === 0) {
|
|
673
|
+
return null;
|
|
680
674
|
}
|
|
675
|
+
return connectionInputData;
|
|
681
676
|
}
|
|
677
|
+
return [];
|
|
678
|
+
}
|
|
679
|
+
rethrowLastNodeError(runExecutionData, node) {
|
|
682
680
|
if (runExecutionData.resultData.lastNodeExecuted === node.name &&
|
|
683
681
|
runExecutionData.resultData.error !== undefined) {
|
|
684
682
|
if (runExecutionData.resultData.error.name === 'NodeOperationError' ||
|
|
@@ -689,6 +687,8 @@ class WorkflowExecute {
|
|
|
689
687
|
error.stack = runExecutionData.resultData.error.stack;
|
|
690
688
|
throw error;
|
|
691
689
|
}
|
|
690
|
+
}
|
|
691
|
+
handleExecuteOnce(node, inputData) {
|
|
692
692
|
if (node.executeOnce === true) {
|
|
693
693
|
const newInputData = {};
|
|
694
694
|
for (const connectionType of Object.keys(inputData)) {
|
|
@@ -696,109 +696,145 @@ class WorkflowExecute {
|
|
|
696
696
|
return input && input.slice(0, 1);
|
|
697
697
|
});
|
|
698
698
|
}
|
|
699
|
-
|
|
699
|
+
return newInputData;
|
|
700
700
|
}
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
701
|
+
return inputData;
|
|
702
|
+
}
|
|
703
|
+
reportJsonIncompatibleOutput(data, workflow, node) {
|
|
704
|
+
if (di_1.Container.get(config_1.GlobalConfig).sentry.backendDsn) {
|
|
705
|
+
const jsonCompatibleResult = (0, is_json_compatible_1.isJsonCompatible)(data, new Set(['pairedItem']));
|
|
706
|
+
if (!jsonCompatibleResult.isValid) {
|
|
707
|
+
di_1.Container.get(error_reporter_1.ErrorReporter).error('node execution returned incorrect output', {
|
|
708
|
+
shouldBeLogged: false,
|
|
709
|
+
extra: {
|
|
710
|
+
nodeName: node.name,
|
|
711
|
+
nodeType: node.type,
|
|
712
|
+
nodeVersion: node.typeVersion,
|
|
713
|
+
workflowId: workflow.id,
|
|
714
|
+
workflowName: workflow.name ?? 'Unnamed workflow',
|
|
715
|
+
executionId: this.additionalData.executionId ?? 'unsaved-execution',
|
|
716
|
+
errorPath: jsonCompatibleResult.errorPath,
|
|
717
|
+
errorMessage: jsonCompatibleResult.errorMessage,
|
|
718
|
+
},
|
|
719
|
+
});
|
|
707
720
|
}
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
async executeNode(workflow, node, nodeType, customOperation, additionalData, mode, runExecutionData, runIndex, connectionInputData, inputData, executionData, abortSignal) {
|
|
724
|
+
const closeFunctions = [];
|
|
725
|
+
const context = new node_execution_context_1.ExecuteContext(workflow, node, additionalData, mode, runExecutionData, runIndex, connectionInputData, inputData, executionData, closeFunctions, abortSignal);
|
|
726
|
+
let data = null;
|
|
727
|
+
if (customOperation) {
|
|
728
|
+
data = await customOperation.call(context);
|
|
729
|
+
}
|
|
730
|
+
else if (nodeType.execute) {
|
|
731
|
+
data =
|
|
732
|
+
nodeType instanceof n8n_workflow_1.Node
|
|
733
|
+
? await nodeType.execute(context)
|
|
734
|
+
: await nodeType.execute.call(context);
|
|
735
|
+
}
|
|
736
|
+
this.reportJsonIncompatibleOutput(data, workflow, node);
|
|
737
|
+
const closeFunctionsResults = await Promise.allSettled(closeFunctions.map(async (fn) => await fn()));
|
|
738
|
+
const closingErrors = closeFunctionsResults
|
|
739
|
+
.filter((result) => result.status === 'rejected')
|
|
740
|
+
.map((result) => result.reason);
|
|
741
|
+
if (closingErrors.length > 0) {
|
|
742
|
+
if (closingErrors[0] instanceof Error)
|
|
743
|
+
throw closingErrors[0];
|
|
744
|
+
throw new n8n_workflow_1.ApplicationError("Error on execution node's close function(s)", {
|
|
745
|
+
extra: { nodeName: node.name },
|
|
746
|
+
tags: { nodeType: node.type },
|
|
747
|
+
cause: closingErrors,
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
return { data, hints: context.hints };
|
|
751
|
+
}
|
|
752
|
+
async executePollNode(workflow, node, nodeType, additionalData, mode, inputData) {
|
|
753
|
+
if (mode === 'manual') {
|
|
754
|
+
const context = new node_execution_context_1.PollContext(workflow, node, additionalData, mode, 'manual');
|
|
755
|
+
return { data: await nodeType.poll.call(context) };
|
|
756
|
+
}
|
|
757
|
+
return { data: inputData.main };
|
|
758
|
+
}
|
|
759
|
+
async executeTriggerNode(workflow, node, additionalData, mode, inputData, abortSignal) {
|
|
760
|
+
if (mode === 'manual') {
|
|
761
|
+
const triggerResponse = await di_1.Container.get(triggers_and_pollers_1.TriggersAndPollers).runTrigger(workflow, node, NodeExecuteFunctions.getExecuteTriggerFunctions, additionalData, mode, 'manual');
|
|
762
|
+
if (triggerResponse === undefined) {
|
|
763
|
+
return { data: null };
|
|
713
764
|
}
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
shouldBeLogged: false,
|
|
719
|
-
extra: {
|
|
720
|
-
nodeName: node.name,
|
|
721
|
-
nodeType: node.type,
|
|
722
|
-
nodeVersion: node.typeVersion,
|
|
723
|
-
workflowId: workflow.id,
|
|
724
|
-
workflowName: workflow.name ?? 'Unnamed workflow',
|
|
725
|
-
executionId: this.additionalData.executionId ?? 'unsaved-execution',
|
|
726
|
-
errorPath: jsonCompatibleResult.errorPath,
|
|
727
|
-
errorMessage: jsonCompatibleResult.errorMessage,
|
|
728
|
-
},
|
|
729
|
-
});
|
|
730
|
-
}
|
|
765
|
+
let closeFunction;
|
|
766
|
+
if (triggerResponse.closeFunction) {
|
|
767
|
+
closeFunction = triggerResponse.closeFunction;
|
|
768
|
+
abortSignal?.addEventListener('abort', closeFunction);
|
|
731
769
|
}
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
.filter((result) => result.status === 'rejected')
|
|
735
|
-
.map((result) => result.reason);
|
|
736
|
-
if (closingErrors.length > 0) {
|
|
737
|
-
if (closingErrors[0] instanceof Error)
|
|
738
|
-
throw closingErrors[0];
|
|
739
|
-
throw new n8n_workflow_1.ApplicationError("Error on execution node's close function(s)", {
|
|
740
|
-
extra: { nodeName: node.name },
|
|
741
|
-
tags: { nodeType: node.type },
|
|
742
|
-
cause: closingErrors,
|
|
743
|
-
});
|
|
770
|
+
if (triggerResponse.manualTriggerFunction !== undefined) {
|
|
771
|
+
await triggerResponse.manualTriggerFunction();
|
|
744
772
|
}
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
if (mode === 'manual') {
|
|
749
|
-
const context = new node_execution_context_1.PollContext(workflow, node, additionalData, mode, 'manual');
|
|
750
|
-
return { data: await nodeType.poll.call(context) };
|
|
773
|
+
const response = await triggerResponse.manualTriggerResponse;
|
|
774
|
+
if (response.length === 0) {
|
|
775
|
+
return { data: null, closeFunction };
|
|
751
776
|
}
|
|
752
|
-
return { data:
|
|
777
|
+
return { data: response, closeFunction };
|
|
753
778
|
}
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
}
|
|
768
|
-
const response = await triggerResponse.manualTriggerResponse;
|
|
769
|
-
if (response.length === 0) {
|
|
770
|
-
return { data: null, closeFunction };
|
|
771
|
-
}
|
|
772
|
-
return { data: response, closeFunction };
|
|
773
|
-
}
|
|
774
|
-
return { data: inputData.main };
|
|
779
|
+
return { data: inputData.main };
|
|
780
|
+
}
|
|
781
|
+
async executeDeclarativeNodeInTest(workflow, node, nodeType, additionalData, mode, runExecutionData, runIndex, connectionInputData, inputData, executionData) {
|
|
782
|
+
const context = new node_execution_context_1.ExecuteContext(workflow, node, additionalData, mode, runExecutionData, runIndex, connectionInputData, inputData, executionData, []);
|
|
783
|
+
const routingNode = new routing_node_1.RoutingNode(context, nodeType);
|
|
784
|
+
const data = await routingNode.runNode();
|
|
785
|
+
return { data };
|
|
786
|
+
}
|
|
787
|
+
async runNode(workflow, executionData, runExecutionData, runIndex, additionalData, mode, abortSignal) {
|
|
788
|
+
const { node } = executionData;
|
|
789
|
+
let inputData = executionData.data;
|
|
790
|
+
if (node.disabled === true) {
|
|
791
|
+
return this.handleDisabledNode(inputData);
|
|
775
792
|
}
|
|
776
|
-
|
|
777
|
-
|
|
793
|
+
const nodeType = workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
|
|
794
|
+
const customOperation = this.getCustomOperation(node, nodeType);
|
|
795
|
+
const connectionInputData = this.prepareConnectionInputData(workflow, nodeType, customOperation, inputData);
|
|
796
|
+
if (connectionInputData === null) {
|
|
797
|
+
return { data: undefined };
|
|
778
798
|
}
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
return
|
|
799
|
+
this.rethrowLastNodeError(runExecutionData, node);
|
|
800
|
+
inputData = this.handleExecuteOnce(node, inputData);
|
|
801
|
+
const isDeclarativeNode = nodeType.description.requestDefaults !== undefined;
|
|
802
|
+
if (nodeType.execute || customOperation) {
|
|
803
|
+
return await this.executeNode(workflow, node, nodeType, customOperation, additionalData, mode, runExecutionData, runIndex, connectionInputData, inputData, executionData, abortSignal);
|
|
804
|
+
}
|
|
805
|
+
if (nodeType.poll) {
|
|
806
|
+
return await this.executePollNode(workflow, node, nodeType, additionalData, mode, inputData);
|
|
784
807
|
}
|
|
808
|
+
if (nodeType.trigger) {
|
|
809
|
+
return await this.executeTriggerNode(workflow, node, additionalData, mode, inputData, abortSignal);
|
|
810
|
+
}
|
|
811
|
+
if (nodeType.webhook && !isDeclarativeNode) {
|
|
812
|
+
return { data: inputData.main };
|
|
813
|
+
}
|
|
814
|
+
return await this.executeDeclarativeNodeInTest(workflow, node, nodeType, additionalData, mode, runExecutionData, runIndex, connectionInputData, inputData, executionData);
|
|
785
815
|
}
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
const forceInputNodeExecution = this.forceInputNodeExecution(workflow);
|
|
790
|
-
this.status = 'running';
|
|
791
|
-
const { hooks, executionId } = this.additionalData;
|
|
792
|
-
assert.ok(hooks, 'Failed to run workflow due to missing execution lifecycle hooks');
|
|
793
|
-
if (!this.runExecutionData.executionData) {
|
|
794
|
-
throw new n8n_workflow_1.ApplicationError('Failed to run workflow due to missing execution data', {
|
|
816
|
+
assertExecutionDataExists(executionData, workflow) {
|
|
817
|
+
if (!executionData) {
|
|
818
|
+
throw new n8n_workflow_1.UnexpectedError('Failed to run workflow due to missing execution data', {
|
|
795
819
|
extra: {
|
|
796
820
|
workflowId: workflow.id,
|
|
797
|
-
executionId,
|
|
821
|
+
executionId: this.additionalData.executionId,
|
|
798
822
|
mode: this.mode,
|
|
799
823
|
},
|
|
800
824
|
});
|
|
801
825
|
}
|
|
826
|
+
}
|
|
827
|
+
handleWaitingState(workflow) {
|
|
828
|
+
if (this.runExecutionData.waitTill) {
|
|
829
|
+
this.runExecutionData.waitTill = undefined;
|
|
830
|
+
this.assertExecutionDataExists(this.runExecutionData.executionData, workflow);
|
|
831
|
+
this.runExecutionData.executionData.nodeExecutionStack[0].node.disabled = true;
|
|
832
|
+
const lastNodeExecuted = this.runExecutionData.resultData.lastNodeExecuted;
|
|
833
|
+
this.runExecutionData.resultData.runData[lastNodeExecuted].pop();
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
checkForWorkflowIssues(workflow) {
|
|
837
|
+
this.assertExecutionDataExists(this.runExecutionData.executionData, workflow);
|
|
802
838
|
const startNode = this.runExecutionData.executionData.nodeExecutionStack.at(0)?.node.name;
|
|
803
839
|
let destinationNode;
|
|
804
840
|
if (this.runExecutionData.startData && this.runExecutionData.startData.destinationNode) {
|
|
@@ -813,19 +849,25 @@ class WorkflowExecute {
|
|
|
813
849
|
if (workflowIssues !== null) {
|
|
814
850
|
throw new workflow_has_issues_error_1.WorkflowHasIssuesError();
|
|
815
851
|
}
|
|
852
|
+
}
|
|
853
|
+
setupExecution() {
|
|
854
|
+
this.status = 'running';
|
|
855
|
+
const { hooks } = this.additionalData;
|
|
856
|
+
assert.ok(hooks, 'Failed to run workflow due to missing execution lifecycle hooks');
|
|
857
|
+
if (this.runExecutionData.startData === undefined) {
|
|
858
|
+
this.runExecutionData.startData = {};
|
|
859
|
+
}
|
|
860
|
+
return { startedAt: new Date(), hooks };
|
|
861
|
+
}
|
|
862
|
+
processRunExecutionData(workflow) {
|
|
863
|
+
n8n_workflow_1.LoggerProxy.debug('Workflow execution started', { workflowId: workflow.id });
|
|
864
|
+
const { startedAt, hooks } = this.setupExecution();
|
|
865
|
+
this.checkForWorkflowIssues(workflow);
|
|
866
|
+
this.handleWaitingState(workflow);
|
|
816
867
|
let executionData;
|
|
817
868
|
let executionError;
|
|
818
869
|
let executionNode;
|
|
819
870
|
let runIndex;
|
|
820
|
-
if (this.runExecutionData.startData === undefined) {
|
|
821
|
-
this.runExecutionData.startData = {};
|
|
822
|
-
}
|
|
823
|
-
if (this.runExecutionData.waitTill) {
|
|
824
|
-
const lastNodeExecuted = this.runExecutionData.resultData.lastNodeExecuted;
|
|
825
|
-
this.runExecutionData.executionData.nodeExecutionStack[0].node.disabled = true;
|
|
826
|
-
this.runExecutionData.waitTill = undefined;
|
|
827
|
-
this.runExecutionData.resultData.runData[lastNodeExecuted].pop();
|
|
828
|
-
}
|
|
829
871
|
let currentExecutionTry = '';
|
|
830
872
|
let lastExecutionTry = '';
|
|
831
873
|
let closeFunction;
|
|
@@ -910,7 +952,7 @@ class WorkflowExecute {
|
|
|
910
952
|
}
|
|
911
953
|
executionData.data = newTaskDataConnections;
|
|
912
954
|
runIndex = 0;
|
|
913
|
-
if (this.runExecutionData.resultData.runData
|
|
955
|
+
if (Object.hasOwn(this.runExecutionData.resultData.runData, executionNode.name)) {
|
|
914
956
|
runIndex = this.runExecutionData.resultData.runData[executionNode.name].length;
|
|
915
957
|
}
|
|
916
958
|
currentExecutionTry = `${executionNode.name}:${runIndex}`;
|
|
@@ -1042,7 +1084,7 @@ class WorkflowExecute {
|
|
|
1042
1084
|
});
|
|
1043
1085
|
}
|
|
1044
1086
|
}
|
|
1045
|
-
if (!this.runExecutionData.resultData.runData
|
|
1087
|
+
if (!Object.hasOwn(this.runExecutionData.resultData.runData, executionNode.name)) {
|
|
1046
1088
|
this.runExecutionData.resultData.runData[executionNode.name] = [];
|
|
1047
1089
|
}
|
|
1048
1090
|
const taskData = {
|
|
@@ -1068,7 +1110,7 @@ class WorkflowExecute {
|
|
|
1068
1110
|
]);
|
|
1069
1111
|
if (executionData.node.continueOnFail === true ||
|
|
1070
1112
|
['continueRegularOutput', 'continueErrorOutput'].includes(executionData.node.onError || '')) {
|
|
1071
|
-
if (executionData.data
|
|
1113
|
+
if (Object.hasOwn(executionData.data, 'main') && executionData.data.main.length > 0) {
|
|
1072
1114
|
if (executionData.data.main[0] !== null) {
|
|
1073
1115
|
nodeSuccessData = [executionData.data.main[0]];
|
|
1074
1116
|
}
|
|
@@ -1130,17 +1172,17 @@ class WorkflowExecute {
|
|
|
1130
1172
|
]);
|
|
1131
1173
|
continue;
|
|
1132
1174
|
}
|
|
1133
|
-
if (workflow.connectionsBySourceNode
|
|
1134
|
-
if (workflow.connectionsBySourceNode[executionNode.name]
|
|
1175
|
+
if (Object.hasOwn(workflow.connectionsBySourceNode, executionNode.name)) {
|
|
1176
|
+
if (Object.hasOwn(workflow.connectionsBySourceNode[executionNode.name], 'main')) {
|
|
1135
1177
|
let outputIndex;
|
|
1136
1178
|
let connectionData;
|
|
1137
1179
|
const nodesToAdd = [];
|
|
1138
1180
|
for (outputIndex in workflow.connectionsBySourceNode[executionNode.name].main) {
|
|
1139
|
-
if (!workflow.connectionsBySourceNode[executionNode.name].main
|
|
1181
|
+
if (!Object.hasOwn(workflow.connectionsBySourceNode[executionNode.name].main, outputIndex)) {
|
|
1140
1182
|
continue;
|
|
1141
1183
|
}
|
|
1142
1184
|
for (connectionData of workflow.connectionsBySourceNode[executionNode.name].main[outputIndex] ?? []) {
|
|
1143
|
-
if (!workflow.nodes
|
|
1185
|
+
if (!Object.hasOwn(workflow.nodes, connectionData.node)) {
|
|
1144
1186
|
throw new n8n_workflow_1.ApplicationError('Destination node not found', {
|
|
1145
1187
|
extra: {
|
|
1146
1188
|
sourceNodeName: executionNode.name,
|
|
@@ -1150,7 +1192,7 @@ class WorkflowExecute {
|
|
|
1150
1192
|
}
|
|
1151
1193
|
if (nodeSuccessData[outputIndex] &&
|
|
1152
1194
|
(nodeSuccessData[outputIndex].length !== 0 ||
|
|
1153
|
-
(connectionData.index > 0 &&
|
|
1195
|
+
(connectionData.index > 0 && this.isLegacyExecutionOrder(workflow)))) {
|
|
1154
1196
|
if (workflow.settings.executionOrder === 'v1') {
|
|
1155
1197
|
const nodeToAdd = workflow.getNode(connectionData.node);
|
|
1156
1198
|
nodesToAdd.push({
|
|
@@ -1323,11 +1365,11 @@ class WorkflowExecute {
|
|
|
1323
1365
|
if (highestNodes.length === 0) {
|
|
1324
1366
|
return true;
|
|
1325
1367
|
}
|
|
1326
|
-
if (!executionData.data
|
|
1368
|
+
if (!Object.hasOwn(executionData.data, 'main')) {
|
|
1327
1369
|
this.runExecutionData.executionData.nodeExecutionStack.push(executionData);
|
|
1328
1370
|
return false;
|
|
1329
1371
|
}
|
|
1330
|
-
if (this.
|
|
1372
|
+
if (this.isLegacyExecutionOrder(workflow)) {
|
|
1331
1373
|
if (executionData.data.main.length < connectionIndex ||
|
|
1332
1374
|
executionData.data.main[connectionIndex] === null) {
|
|
1333
1375
|
this.runExecutionData.executionData.nodeExecutionStack.push(executionData);
|