This commit is contained in:
Srinjoy 2026-05-12 14:26:15 +02:00 committed by GitHub
commit 0541e251a5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 37 additions and 9 deletions

View File

@ -46,9 +46,11 @@ import {
} from 'n8n-workflow';
import assert from 'node:assert';
import * as Helpers from '@test/helpers';
import { legacyWorkflowExecuteTests, v1WorkflowExecuteTests } from '@test/helpers/constants';
import * as Helpers from '../../../test/helpers';
import {
legacyWorkflowExecuteTests,
v1WorkflowExecuteTests,
} from '../../../test/helpers/constants';
import type { ExecutionLifecycleHooks } from '../execution-lifecycle-hooks';
import { DirectedGraph } from '../partial-execution-utils';
import * as partialExecutionUtils from '../partial-execution-utils';
@ -80,6 +82,34 @@ describe('WorkflowExecute', () => {
.mockImplementation(() => {});
});
it('should not trigger retry when error field is null', async () => {
const retryNode: INode = {
...createNodeData({ name: 'retryNode' }),
retryOnFail: true,
maxTries: 3,
waitBetweenTries: 1,
};
const workflow = new Workflow({
id: 'test',
nodes: [retryNode],
connections: {},
active: false,
nodeTypes,
});
const waitPromise = createDeferredPromise<IRun>();
const additionalData = Helpers.WorkflowExecuteAdditionalData(waitPromise);
const workflowExecute = new WorkflowExecute(additionalData, 'manual');
const runNodeSpy = jest.spyOn(workflowExecute, 'runNode').mockResolvedValue({
data: [[{ json: { error: null } }]],
});
await workflowExecute.run({ workflow, startNode: retryNode });
const result = await waitPromise.promise;
expect(result.finished).toBe(true);
expect(runNodeSpy).toHaveBeenCalledTimes(1);
});
describe('v0 execution order', () => {
const tests: WorkflowTestData[] = legacyWorkflowExecuteTests;

View File

@ -1626,6 +1626,8 @@ export class WorkflowExecute {
await hooks.runHook('nodeExecuteBefore', [executionNode.name, taskStartedData]);
}
let maxTries = 1;
const checkFailure = (data: IRunNodeResponse | EngineRequest) =>
!isEngineRequest(data) && !!data.data?.[0]?.[0]?.json?.error;
if (executionData.node.retryOnFail === true) {
// TODO: Remove the hardcoded default-values here and also in NodeSettings.vue
maxTries = Math.min(5, Math.max(2, executionData.node.maxTries || 3));
@ -1695,9 +1697,7 @@ export class WorkflowExecute {
subNodeExecutionResults,
);
let nodeFailed =
!isEngineRequest(runNodeData) &&
runNodeData.data?.[0]?.[0]?.json?.error !== undefined;
let nodeFailed = checkFailure(runNodeData);
while (nodeFailed && tryIndex !== maxTries - 1) {
await sleep(waitBetweenTries);
@ -1712,9 +1712,7 @@ export class WorkflowExecute {
this.abortController.signal,
);
nodeFailed =
!isEngineRequest(runNodeData) &&
runNodeData.data?.[0]?.[0]?.json?.error !== undefined;
nodeFailed = checkFailure(runNodeData);
tryIndex++;
}