n8n-core 1.72.1 → 1.74.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/LICENSE.md +5 -3
- package/dist/ActiveWorkflows.d.ts +9 -3
- package/dist/ActiveWorkflows.js +25 -14
- package/dist/ActiveWorkflows.js.map +1 -1
- package/dist/BinaryData/BinaryData.service.js +3 -3
- package/dist/BinaryData/BinaryData.service.js.map +1 -1
- package/dist/BinaryData/ObjectStore.manager.js +2 -2
- package/dist/BinaryData/ObjectStore.manager.js.map +1 -1
- package/dist/Cipher.js +2 -2
- package/dist/Cipher.js.map +1 -1
- package/dist/Constants.d.ts +5 -0
- package/dist/Constants.js +29 -1
- package/dist/Constants.js.map +1 -1
- package/dist/CreateNodeAsTool.d.ts +2 -2
- package/dist/CreateNodeAsTool.js +30 -44
- package/dist/CreateNodeAsTool.js.map +1 -1
- package/dist/Credentials.js +2 -2
- package/dist/Credentials.js.map +1 -1
- package/dist/DirectoryLoader.d.ts +3 -0
- package/dist/DirectoryLoader.js +26 -6
- package/dist/DirectoryLoader.js.map +1 -1
- package/dist/InstanceSettings.d.ts +11 -3
- package/dist/InstanceSettings.js +53 -24
- package/dist/InstanceSettings.js.map +1 -1
- package/dist/InstanceSettingsConfig.d.ts +3 -0
- package/dist/InstanceSettingsConfig.js +9 -1
- package/dist/InstanceSettingsConfig.js.map +1 -1
- package/dist/NodeExecuteFunctions.d.ts +2 -7
- package/dist/NodeExecuteFunctions.js +27 -125
- package/dist/NodeExecuteFunctions.js.map +1 -1
- package/dist/ObjectStore/ObjectStore.service.ee.d.ts +3 -1
- package/dist/ObjectStore/ObjectStore.service.ee.js +9 -4
- package/dist/ObjectStore/ObjectStore.service.ee.js.map +1 -1
- package/dist/RoutingNode.d.ts +18 -0
- package/dist/RoutingNode.js +560 -0
- package/dist/RoutingNode.js.map +1 -0
- package/dist/SSHClientsManager.js +2 -2
- package/dist/SSHClientsManager.js.map +1 -1
- package/dist/ScheduledTaskManager.js +2 -2
- package/dist/ScheduledTaskManager.js.map +1 -1
- package/dist/SerializedBuffer.d.ts +6 -0
- package/dist/SerializedBuffer.js +16 -0
- package/dist/SerializedBuffer.js.map +1 -0
- package/dist/TriggersAndPollers.d.ts +5 -0
- package/dist/TriggersAndPollers.js +70 -0
- package/dist/TriggersAndPollers.js.map +1 -0
- package/dist/WorkflowExecute.d.ts +9 -1
- package/dist/WorkflowExecute.js +267 -117
- package/dist/WorkflowExecute.js.map +1 -1
- package/dist/build.tsbuildinfo +1 -1
- package/dist/decorators/index.d.ts +1 -0
- package/dist/decorators/index.js +6 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/decorators/memoized.d.ts +1 -0
- package/dist/decorators/memoized.js +23 -0
- package/dist/decorators/memoized.js.map +1 -0
- package/dist/error-reporter.d.ts +18 -0
- package/dist/error-reporter.js +184 -0
- package/dist/error-reporter.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/logging/logger.d.ts +34 -0
- package/dist/logging/logger.js +210 -0
- package/dist/logging/logger.js.map +1 -0
- package/dist/node-execution-context/base-execute-context.d.ts +1 -3
- package/dist/node-execution-context/base-execute-context.js +2 -10
- package/dist/node-execution-context/base-execute-context.js.map +1 -1
- package/dist/node-execution-context/execute-context.d.ts +2 -2
- package/dist/node-execution-context/execute-context.js +4 -2
- package/dist/node-execution-context/execute-context.js.map +1 -1
- package/dist/node-execution-context/execute-single-context.js +1 -0
- package/dist/node-execution-context/execute-single-context.js.map +1 -1
- package/dist/node-execution-context/index.d.ts +2 -1
- package/dist/node-execution-context/index.js +5 -3
- package/dist/node-execution-context/index.js.map +1 -1
- package/dist/node-execution-context/local-load-options-context.d.ts +10 -0
- package/dist/node-execution-context/local-load-options-context.js +49 -0
- package/dist/node-execution-context/local-load-options-context.js.map +1 -0
- package/dist/node-execution-context/node-execution-context.d.ts +10 -4
- package/dist/node-execution-context/node-execution-context.js +70 -8
- package/dist/node-execution-context/node-execution-context.js.map +1 -1
- package/dist/node-execution-context/supply-data-context.d.ts +5 -6
- package/dist/node-execution-context/supply-data-context.js +9 -19
- package/dist/node-execution-context/supply-data-context.js.map +1 -1
- package/dist/node-execution-context/utils/cleanupParameterData.d.ts +2 -0
- package/dist/node-execution-context/utils/cleanupParameterData.js +27 -0
- package/dist/node-execution-context/utils/cleanupParameterData.js.map +1 -0
- package/dist/node-execution-context/utils/ensureType.d.ts +6 -0
- package/dist/node-execution-context/utils/ensureType.js +75 -0
- package/dist/node-execution-context/utils/ensureType.js.map +1 -0
- package/dist/node-execution-context/utils/getAdditionalKeys.d.ts +4 -0
- package/dist/node-execution-context/utils/getAdditionalKeys.js +57 -0
- package/dist/node-execution-context/utils/getAdditionalKeys.js.map +1 -0
- package/dist/node-execution-context/utils/getInputConnectionData.d.ts +4 -0
- package/dist/node-execution-context/utils/getInputConnectionData.js +99 -0
- package/dist/node-execution-context/utils/getInputConnectionData.js.map +1 -0
- package/dist/node-execution-context/utils/validateValueAgainstSchema.d.ts +2 -0
- package/dist/node-execution-context/utils/validateValueAgainstSchema.js +129 -0
- package/dist/node-execution-context/utils/validateValueAgainstSchema.js.map +1 -0
- package/dist/node-execution-context/webhook-context.d.ts +2 -2
- package/dist/node-execution-context/webhook-context.js +2 -1
- package/dist/node-execution-context/webhook-context.js.map +1 -1
- package/dist/node-execution-context/workflow-node-context.d.ts +6 -0
- package/dist/node-execution-context/workflow-node-context.js +14 -0
- package/dist/node-execution-context/workflow-node-context.js.map +1 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +10 -0
- package/dist/utils.js.map +1 -0
- package/package.json +13 -8
- package/dist/node-execution-context/utils.d.ts +0 -11
- package/dist/node-execution-context/utils.js +0 -275
- package/dist/node-execution-context/utils.js.map +0 -1
package/dist/WorkflowExecute.js
CHANGED
|
@@ -37,14 +37,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.WorkflowExecute = void 0;
|
|
40
|
+
const di_1 = require("@n8n/di");
|
|
40
41
|
const assert = __importStar(require("assert/strict"));
|
|
41
42
|
const events_1 = require("events");
|
|
42
43
|
const lodash_1 = require("lodash");
|
|
43
44
|
const get_1 = __importDefault(require("lodash/get"));
|
|
44
45
|
const n8n_workflow_1 = require("n8n-workflow");
|
|
45
46
|
const p_cancelable_1 = __importDefault(require("p-cancelable"));
|
|
47
|
+
const error_reporter_1 = require("./error-reporter");
|
|
48
|
+
const node_execution_context_1 = require("./node-execution-context");
|
|
46
49
|
const NodeExecuteFunctions = __importStar(require("./NodeExecuteFunctions"));
|
|
47
50
|
const PartialExecutionUtils_1 = require("./PartialExecutionUtils");
|
|
51
|
+
const RoutingNode_1 = require("./RoutingNode");
|
|
52
|
+
const TriggersAndPollers_1 = require("./TriggersAndPollers");
|
|
48
53
|
class WorkflowExecute {
|
|
49
54
|
constructor(additionalData, mode, runExecutionData = {
|
|
50
55
|
startData: {},
|
|
@@ -304,18 +309,16 @@ class WorkflowExecute {
|
|
|
304
309
|
return true;
|
|
305
310
|
}
|
|
306
311
|
prepareWaitingToExecution(nodeName, numberOfConnections, runIndex) {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
};
|
|
313
|
-
|
|
314
|
-
main: [],
|
|
315
|
-
};
|
|
312
|
+
const executionData = this.runExecutionData.executionData;
|
|
313
|
+
executionData.waitingExecution ??= {};
|
|
314
|
+
executionData.waitingExecutionSource ??= {};
|
|
315
|
+
const nodeWaiting = (executionData.waitingExecution[nodeName] ??= []);
|
|
316
|
+
const nodeWaitingSource = (executionData.waitingExecutionSource[nodeName] ??= []);
|
|
317
|
+
nodeWaiting[runIndex] = { main: [] };
|
|
318
|
+
nodeWaitingSource[runIndex] = { main: [] };
|
|
316
319
|
for (let i = 0; i < numberOfConnections; i++) {
|
|
317
|
-
|
|
318
|
-
|
|
320
|
+
nodeWaiting[runIndex].main.push(null);
|
|
321
|
+
nodeWaitingSource[runIndex].main.push(null);
|
|
319
322
|
}
|
|
320
323
|
}
|
|
321
324
|
addNodeToBeExecuted(workflow, connectionData, outputIndex, parentNodeName, nodeSuccessData, runIndex) {
|
|
@@ -536,6 +539,151 @@ class WorkflowExecute {
|
|
|
536
539
|
});
|
|
537
540
|
}
|
|
538
541
|
}
|
|
542
|
+
checkReadyForExecution(workflow, inputData = {}) {
|
|
543
|
+
const workflowIssues = {};
|
|
544
|
+
let checkNodes = [];
|
|
545
|
+
if (inputData.destinationNode) {
|
|
546
|
+
checkNodes = workflow.getParentNodes(inputData.destinationNode);
|
|
547
|
+
checkNodes.push(inputData.destinationNode);
|
|
548
|
+
}
|
|
549
|
+
else if (inputData.startNode) {
|
|
550
|
+
checkNodes = workflow.getChildNodes(inputData.startNode);
|
|
551
|
+
checkNodes.push(inputData.startNode);
|
|
552
|
+
}
|
|
553
|
+
for (const nodeName of checkNodes) {
|
|
554
|
+
let nodeIssues = null;
|
|
555
|
+
const node = workflow.nodes[nodeName];
|
|
556
|
+
if (node.disabled === true) {
|
|
557
|
+
continue;
|
|
558
|
+
}
|
|
559
|
+
const nodeType = workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
|
|
560
|
+
if (nodeType === undefined) {
|
|
561
|
+
nodeIssues = {
|
|
562
|
+
typeUnknown: true,
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
else {
|
|
566
|
+
nodeIssues = n8n_workflow_1.NodeHelpers.getNodeParametersIssues(nodeType.description.properties, node, inputData.pinDataNodeNames);
|
|
567
|
+
}
|
|
568
|
+
if (nodeIssues !== null) {
|
|
569
|
+
workflowIssues[node.name] = nodeIssues;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
if (Object.keys(workflowIssues).length === 0) {
|
|
573
|
+
return null;
|
|
574
|
+
}
|
|
575
|
+
return workflowIssues;
|
|
576
|
+
}
|
|
577
|
+
async runNode(workflow, executionData, runExecutionData, runIndex, additionalData, mode, abortSignal) {
|
|
578
|
+
const { node } = executionData;
|
|
579
|
+
let inputData = executionData.data;
|
|
580
|
+
if (node.disabled === true) {
|
|
581
|
+
if (inputData.hasOwnProperty('main') && inputData.main.length > 0) {
|
|
582
|
+
if (inputData.main[0] === null) {
|
|
583
|
+
return { data: undefined };
|
|
584
|
+
}
|
|
585
|
+
return { data: [inputData.main[0]] };
|
|
586
|
+
}
|
|
587
|
+
return { data: undefined };
|
|
588
|
+
}
|
|
589
|
+
const nodeType = workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
|
|
590
|
+
let connectionInputData = [];
|
|
591
|
+
if (nodeType.execute || (!nodeType.poll && !nodeType.trigger && !nodeType.webhook)) {
|
|
592
|
+
if (inputData.main?.length > 0) {
|
|
593
|
+
connectionInputData = inputData.main[0];
|
|
594
|
+
}
|
|
595
|
+
const forceInputNodeExecution = workflow.settings.executionOrder !== 'v1';
|
|
596
|
+
if (!forceInputNodeExecution) {
|
|
597
|
+
for (const mainData of inputData.main) {
|
|
598
|
+
if (mainData?.length) {
|
|
599
|
+
connectionInputData = mainData;
|
|
600
|
+
break;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
if (connectionInputData.length === 0) {
|
|
605
|
+
return { data: undefined };
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
if (runExecutionData.resultData.lastNodeExecuted === node.name &&
|
|
609
|
+
runExecutionData.resultData.error !== undefined) {
|
|
610
|
+
if (runExecutionData.resultData.error.name === 'NodeOperationError' ||
|
|
611
|
+
runExecutionData.resultData.error.name === 'NodeApiError') {
|
|
612
|
+
throw runExecutionData.resultData.error;
|
|
613
|
+
}
|
|
614
|
+
const error = new Error(runExecutionData.resultData.error.message);
|
|
615
|
+
error.stack = runExecutionData.resultData.error.stack;
|
|
616
|
+
throw error;
|
|
617
|
+
}
|
|
618
|
+
if (node.executeOnce === true) {
|
|
619
|
+
const newInputData = {};
|
|
620
|
+
for (const connectionType of Object.keys(inputData)) {
|
|
621
|
+
newInputData[connectionType] = inputData[connectionType].map((input) => {
|
|
622
|
+
return input && input.slice(0, 1);
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
inputData = newInputData;
|
|
626
|
+
}
|
|
627
|
+
if (nodeType.execute) {
|
|
628
|
+
const closeFunctions = [];
|
|
629
|
+
const context = new node_execution_context_1.ExecuteContext(workflow, node, additionalData, mode, runExecutionData, runIndex, connectionInputData, inputData, executionData, closeFunctions, abortSignal);
|
|
630
|
+
const data = nodeType instanceof n8n_workflow_1.Node
|
|
631
|
+
? await nodeType.execute(context)
|
|
632
|
+
: await nodeType.execute.call(context);
|
|
633
|
+
const closeFunctionsResults = await Promise.allSettled(closeFunctions.map(async (fn) => await fn()));
|
|
634
|
+
const closingErrors = closeFunctionsResults
|
|
635
|
+
.filter((result) => result.status === 'rejected')
|
|
636
|
+
.map((result) => result.reason);
|
|
637
|
+
if (closingErrors.length > 0) {
|
|
638
|
+
if (closingErrors[0] instanceof Error)
|
|
639
|
+
throw closingErrors[0];
|
|
640
|
+
throw new n8n_workflow_1.ApplicationError("Error on execution node's close function(s)", {
|
|
641
|
+
extra: { nodeName: node.name },
|
|
642
|
+
tags: { nodeType: node.type },
|
|
643
|
+
cause: closingErrors,
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
return { data };
|
|
647
|
+
}
|
|
648
|
+
else if (nodeType.poll) {
|
|
649
|
+
if (mode === 'manual') {
|
|
650
|
+
const context = new node_execution_context_1.PollContext(workflow, node, additionalData, mode, 'manual');
|
|
651
|
+
return { data: await nodeType.poll.call(context) };
|
|
652
|
+
}
|
|
653
|
+
return { data: inputData.main };
|
|
654
|
+
}
|
|
655
|
+
else if (nodeType.trigger) {
|
|
656
|
+
if (mode === 'manual') {
|
|
657
|
+
const triggerResponse = await di_1.Container.get(TriggersAndPollers_1.TriggersAndPollers).runTrigger(workflow, node, NodeExecuteFunctions.getExecuteTriggerFunctions, additionalData, mode, 'manual');
|
|
658
|
+
if (triggerResponse === undefined) {
|
|
659
|
+
return { data: null };
|
|
660
|
+
}
|
|
661
|
+
let closeFunction;
|
|
662
|
+
if (triggerResponse.closeFunction) {
|
|
663
|
+
closeFunction = triggerResponse.closeFunction;
|
|
664
|
+
abortSignal?.addEventListener('abort', closeFunction);
|
|
665
|
+
}
|
|
666
|
+
if (triggerResponse.manualTriggerFunction !== undefined) {
|
|
667
|
+
await triggerResponse.manualTriggerFunction();
|
|
668
|
+
}
|
|
669
|
+
const response = await triggerResponse.manualTriggerResponse;
|
|
670
|
+
if (response.length === 0) {
|
|
671
|
+
return { data: null, closeFunction };
|
|
672
|
+
}
|
|
673
|
+
return { data: response, closeFunction };
|
|
674
|
+
}
|
|
675
|
+
return { data: inputData.main };
|
|
676
|
+
}
|
|
677
|
+
else if (nodeType.webhook) {
|
|
678
|
+
return { data: inputData.main };
|
|
679
|
+
}
|
|
680
|
+
else {
|
|
681
|
+
const routingNode = new RoutingNode_1.RoutingNode(workflow, node, connectionInputData, runExecutionData ?? null, additionalData, mode);
|
|
682
|
+
return {
|
|
683
|
+
data: await routingNode.runNode(inputData, runIndex, nodeType, executionData, undefined, abortSignal),
|
|
684
|
+
};
|
|
685
|
+
}
|
|
686
|
+
}
|
|
539
687
|
processRunExecutionData(workflow) {
|
|
540
688
|
n8n_workflow_1.LoggerProxy.debug('Workflow execution started', { workflowId: workflow.id });
|
|
541
689
|
const startedAt = new Date();
|
|
@@ -547,13 +695,13 @@ class WorkflowExecute {
|
|
|
547
695
|
destinationNode = this.runExecutionData.startData.destinationNode;
|
|
548
696
|
}
|
|
549
697
|
const pinDataNodeNames = Object.keys(this.runExecutionData.resultData.pinData ?? {});
|
|
550
|
-
const workflowIssues =
|
|
698
|
+
const workflowIssues = this.checkReadyForExecution(workflow, {
|
|
551
699
|
startNode,
|
|
552
700
|
destinationNode,
|
|
553
701
|
pinDataNodeNames,
|
|
554
702
|
});
|
|
555
703
|
if (workflowIssues !== null) {
|
|
556
|
-
throw new n8n_workflow_1.WorkflowOperationError('The workflow has issues and
|
|
704
|
+
throw new n8n_workflow_1.WorkflowOperationError('The workflow has issues and cannot be executed for that reason. Please fix them first.');
|
|
557
705
|
}
|
|
558
706
|
let executionData;
|
|
559
707
|
let executionError;
|
|
@@ -721,12 +869,12 @@ class WorkflowExecute {
|
|
|
721
869
|
node: executionNode.name,
|
|
722
870
|
workflowId: workflow.id,
|
|
723
871
|
});
|
|
724
|
-
let runNodeData = await
|
|
872
|
+
let runNodeData = await this.runNode(workflow, executionData, this.runExecutionData, runIndex, this.additionalData, this.mode, this.abortController.signal);
|
|
725
873
|
nodeSuccessData = runNodeData.data;
|
|
726
874
|
const didContinueOnFail = nodeSuccessData?.at(0)?.at(0)?.json?.error !== undefined;
|
|
727
875
|
while (didContinueOnFail && tryIndex !== maxTries - 1) {
|
|
728
876
|
await (0, n8n_workflow_1.sleep)(waitBetweenTries);
|
|
729
|
-
runNodeData = await
|
|
877
|
+
runNodeData = await this.runNode(workflow, executionData, this.runExecutionData, runIndex, this.additionalData, this.mode, this.abortController.signal);
|
|
730
878
|
tryIndex++;
|
|
731
879
|
}
|
|
732
880
|
if (nodeSuccessData instanceof n8n_workflow_1.NodeExecutionOutput) {
|
|
@@ -734,71 +882,7 @@ class WorkflowExecute {
|
|
|
734
882
|
executionHints.push(...hints);
|
|
735
883
|
}
|
|
736
884
|
if (nodeSuccessData && executionData.node.onError === 'continueErrorOutput') {
|
|
737
|
-
|
|
738
|
-
const outputs = n8n_workflow_1.NodeHelpers.getNodeOutputs(workflow, executionData.node, nodeType.description);
|
|
739
|
-
const outputTypes = n8n_workflow_1.NodeHelpers.getConnectionTypes(outputs);
|
|
740
|
-
const mainOutputTypes = outputTypes.filter((output) => output === "main");
|
|
741
|
-
const errorItems = [];
|
|
742
|
-
const closeFunctions = [];
|
|
743
|
-
const executeFunctions = NodeExecuteFunctions.getExecuteFunctions(workflow, this.runExecutionData, runIndex, [], executionData.data, executionData.node, this.additionalData, executionData, this.mode, closeFunctions, this.abortController.signal);
|
|
744
|
-
const dataProxy = executeFunctions.getWorkflowDataProxy(0);
|
|
745
|
-
for (let outputIndex = 0; outputIndex < mainOutputTypes.length - 1; outputIndex++) {
|
|
746
|
-
const successItems = [];
|
|
747
|
-
const items = nodeSuccessData[outputIndex]?.length
|
|
748
|
-
? nodeSuccessData[outputIndex]
|
|
749
|
-
: [];
|
|
750
|
-
while (items.length) {
|
|
751
|
-
const item = items.shift();
|
|
752
|
-
if (item === undefined) {
|
|
753
|
-
continue;
|
|
754
|
-
}
|
|
755
|
-
let errorData;
|
|
756
|
-
if (item.error) {
|
|
757
|
-
errorData = item.error;
|
|
758
|
-
item.error = undefined;
|
|
759
|
-
}
|
|
760
|
-
else if (item.json.error && Object.keys(item.json).length === 1) {
|
|
761
|
-
errorData = item.json.error;
|
|
762
|
-
}
|
|
763
|
-
else if (item.json.error &&
|
|
764
|
-
item.json.message &&
|
|
765
|
-
Object.keys(item.json).length === 2) {
|
|
766
|
-
errorData = item.json.error;
|
|
767
|
-
}
|
|
768
|
-
if (errorData) {
|
|
769
|
-
const pairedItemData = item.pairedItem && typeof item.pairedItem === 'object'
|
|
770
|
-
? Array.isArray(item.pairedItem)
|
|
771
|
-
? item.pairedItem[0]
|
|
772
|
-
: item.pairedItem
|
|
773
|
-
: undefined;
|
|
774
|
-
if (executionData.source === null || pairedItemData === undefined) {
|
|
775
|
-
errorItems.push(item);
|
|
776
|
-
}
|
|
777
|
-
else {
|
|
778
|
-
const pairedItemInputIndex = pairedItemData.input || 0;
|
|
779
|
-
const sourceData = executionData.source["main"][pairedItemInputIndex];
|
|
780
|
-
const constPairedItem = dataProxy.$getPairedItem(sourceData.previousNode, sourceData, pairedItemData);
|
|
781
|
-
if (constPairedItem === null) {
|
|
782
|
-
errorItems.push(item);
|
|
783
|
-
}
|
|
784
|
-
else {
|
|
785
|
-
errorItems.push({
|
|
786
|
-
...item,
|
|
787
|
-
json: {
|
|
788
|
-
...constPairedItem.json,
|
|
789
|
-
...item.json,
|
|
790
|
-
},
|
|
791
|
-
});
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
else {
|
|
796
|
-
successItems.push(item);
|
|
797
|
-
}
|
|
798
|
-
}
|
|
799
|
-
nodeSuccessData[outputIndex] = successItems;
|
|
800
|
-
}
|
|
801
|
-
nodeSuccessData[mainOutputTypes.length - 1] = errorItems;
|
|
885
|
+
this.handleNodeErrorOutput(workflow, executionData, nodeSuccessData, runIndex);
|
|
802
886
|
}
|
|
803
887
|
if (runNodeData.closeFunction) {
|
|
804
888
|
closeFunction = runNodeData.closeFunction();
|
|
@@ -808,40 +892,7 @@ class WorkflowExecute {
|
|
|
808
892
|
node: executionNode.name,
|
|
809
893
|
workflowId: workflow.id,
|
|
810
894
|
});
|
|
811
|
-
|
|
812
|
-
const isSingleInputAndOutput = executionData.data.main.length === 1 && executionData.data.main[0]?.length === 1;
|
|
813
|
-
const isSameNumberOfItems = nodeSuccessData.length === 1 &&
|
|
814
|
-
executionData.data.main.length === 1 &&
|
|
815
|
-
executionData.data.main[0]?.length === nodeSuccessData[0].length;
|
|
816
|
-
checkOutputData: for (const outputData of nodeSuccessData) {
|
|
817
|
-
if (outputData === null) {
|
|
818
|
-
continue;
|
|
819
|
-
}
|
|
820
|
-
for (const [index, item] of outputData.entries()) {
|
|
821
|
-
if (item.pairedItem === undefined) {
|
|
822
|
-
if (isSingleInputAndOutput) {
|
|
823
|
-
item.pairedItem = {
|
|
824
|
-
item: 0,
|
|
825
|
-
};
|
|
826
|
-
}
|
|
827
|
-
else if (isSameNumberOfItems) {
|
|
828
|
-
item.pairedItem = {
|
|
829
|
-
item: index,
|
|
830
|
-
};
|
|
831
|
-
}
|
|
832
|
-
else {
|
|
833
|
-
break checkOutputData;
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
|
-
if (nodeSuccessData === undefined) {
|
|
840
|
-
nodeSuccessData = null;
|
|
841
|
-
}
|
|
842
|
-
else {
|
|
843
|
-
this.runExecutionData.resultData.lastNodeExecuted = executionData.node.name;
|
|
844
|
-
}
|
|
895
|
+
nodeSuccessData = this.assignPairedItems(nodeSuccessData, executionData);
|
|
845
896
|
if (nodeSuccessData === null || nodeSuccessData[0][0] === undefined) {
|
|
846
897
|
if (executionData.node.alwaysOutputData === true) {
|
|
847
898
|
const pairedItem = [];
|
|
@@ -881,7 +932,7 @@ class WorkflowExecute {
|
|
|
881
932
|
toReport = error;
|
|
882
933
|
}
|
|
883
934
|
if (toReport) {
|
|
884
|
-
|
|
935
|
+
di_1.Container.get(error_reporter_1.ErrorReporter).error(toReport, {
|
|
885
936
|
extra: {
|
|
886
937
|
nodeName: executionNode.name,
|
|
887
938
|
nodeType: executionNode.type,
|
|
@@ -1204,14 +1255,113 @@ class WorkflowExecute {
|
|
|
1204
1255
|
return fullRunData;
|
|
1205
1256
|
}
|
|
1206
1257
|
getFullRunData(startedAt) {
|
|
1207
|
-
|
|
1258
|
+
return {
|
|
1208
1259
|
data: this.runExecutionData,
|
|
1209
1260
|
mode: this.mode,
|
|
1210
1261
|
startedAt,
|
|
1211
1262
|
stoppedAt: new Date(),
|
|
1212
1263
|
status: this.status,
|
|
1213
1264
|
};
|
|
1214
|
-
|
|
1265
|
+
}
|
|
1266
|
+
handleNodeErrorOutput(workflow, executionData, nodeSuccessData, runIndex) {
|
|
1267
|
+
const nodeType = workflow.nodeTypes.getByNameAndVersion(executionData.node.type, executionData.node.typeVersion);
|
|
1268
|
+
const outputs = n8n_workflow_1.NodeHelpers.getNodeOutputs(workflow, executionData.node, nodeType.description);
|
|
1269
|
+
const outputTypes = n8n_workflow_1.NodeHelpers.getConnectionTypes(outputs);
|
|
1270
|
+
const mainOutputTypes = outputTypes.filter((output) => output === "main");
|
|
1271
|
+
const errorItems = [];
|
|
1272
|
+
const closeFunctions = [];
|
|
1273
|
+
const executeFunctions = new node_execution_context_1.ExecuteContext(workflow, executionData.node, this.additionalData, this.mode, this.runExecutionData, runIndex, [], executionData.data, executionData, closeFunctions, this.abortController.signal);
|
|
1274
|
+
const dataProxy = executeFunctions.getWorkflowDataProxy(0);
|
|
1275
|
+
for (let outputIndex = 0; outputIndex < mainOutputTypes.length - 1; outputIndex++) {
|
|
1276
|
+
const successItems = [];
|
|
1277
|
+
const items = nodeSuccessData[outputIndex]?.length ? nodeSuccessData[outputIndex] : [];
|
|
1278
|
+
while (items.length) {
|
|
1279
|
+
const item = items.shift();
|
|
1280
|
+
if (item === undefined) {
|
|
1281
|
+
continue;
|
|
1282
|
+
}
|
|
1283
|
+
let errorData;
|
|
1284
|
+
if (item.error) {
|
|
1285
|
+
errorData = item.error;
|
|
1286
|
+
item.error = undefined;
|
|
1287
|
+
}
|
|
1288
|
+
else if (item.json.error && Object.keys(item.json).length === 1) {
|
|
1289
|
+
errorData = item.json.error;
|
|
1290
|
+
}
|
|
1291
|
+
else if (item.json.error && item.json.message && Object.keys(item.json).length === 2) {
|
|
1292
|
+
errorData = item.json.error;
|
|
1293
|
+
}
|
|
1294
|
+
if (errorData) {
|
|
1295
|
+
const pairedItemData = item.pairedItem && typeof item.pairedItem === 'object'
|
|
1296
|
+
? Array.isArray(item.pairedItem)
|
|
1297
|
+
? item.pairedItem[0]
|
|
1298
|
+
: item.pairedItem
|
|
1299
|
+
: undefined;
|
|
1300
|
+
if (executionData.source === null || pairedItemData === undefined) {
|
|
1301
|
+
errorItems.push(item);
|
|
1302
|
+
}
|
|
1303
|
+
else {
|
|
1304
|
+
const pairedItemInputIndex = pairedItemData.input || 0;
|
|
1305
|
+
const sourceData = executionData.source["main"][pairedItemInputIndex];
|
|
1306
|
+
const constPairedItem = dataProxy.$getPairedItem(sourceData.previousNode, sourceData, pairedItemData);
|
|
1307
|
+
if (constPairedItem === null) {
|
|
1308
|
+
errorItems.push(item);
|
|
1309
|
+
}
|
|
1310
|
+
else {
|
|
1311
|
+
errorItems.push({
|
|
1312
|
+
...item,
|
|
1313
|
+
json: {
|
|
1314
|
+
...constPairedItem.json,
|
|
1315
|
+
...item.json,
|
|
1316
|
+
},
|
|
1317
|
+
});
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
else {
|
|
1322
|
+
successItems.push(item);
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
nodeSuccessData[outputIndex] = successItems;
|
|
1326
|
+
}
|
|
1327
|
+
nodeSuccessData[mainOutputTypes.length - 1] = errorItems;
|
|
1328
|
+
}
|
|
1329
|
+
assignPairedItems(nodeSuccessData, executionData) {
|
|
1330
|
+
if (nodeSuccessData?.length) {
|
|
1331
|
+
const isSingleInputAndOutput = executionData.data.main.length === 1 && executionData.data.main[0]?.length === 1;
|
|
1332
|
+
const isSameNumberOfItems = nodeSuccessData.length === 1 &&
|
|
1333
|
+
executionData.data.main.length === 1 &&
|
|
1334
|
+
executionData.data.main[0]?.length === nodeSuccessData[0].length;
|
|
1335
|
+
checkOutputData: for (const outputData of nodeSuccessData) {
|
|
1336
|
+
if (outputData === null) {
|
|
1337
|
+
continue;
|
|
1338
|
+
}
|
|
1339
|
+
for (const [index, item] of outputData.entries()) {
|
|
1340
|
+
if (item.pairedItem === undefined) {
|
|
1341
|
+
if (isSingleInputAndOutput) {
|
|
1342
|
+
item.pairedItem = {
|
|
1343
|
+
item: 0,
|
|
1344
|
+
};
|
|
1345
|
+
}
|
|
1346
|
+
else if (isSameNumberOfItems) {
|
|
1347
|
+
item.pairedItem = {
|
|
1348
|
+
item: index,
|
|
1349
|
+
};
|
|
1350
|
+
}
|
|
1351
|
+
else {
|
|
1352
|
+
break checkOutputData;
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
if (nodeSuccessData === undefined) {
|
|
1359
|
+
nodeSuccessData = null;
|
|
1360
|
+
}
|
|
1361
|
+
else {
|
|
1362
|
+
this.runExecutionData.resultData.lastNodeExecuted = executionData.node.name;
|
|
1363
|
+
}
|
|
1364
|
+
return nodeSuccessData;
|
|
1215
1365
|
}
|
|
1216
1366
|
get isCancelled() {
|
|
1217
1367
|
return this.abortController.signal.aborted;
|