fix(editor): Rerun failed nodes in manual executions (#9050)

Co-authored-by: Iván Ovejero <ivov.src@gmail.com>
This commit is contained in:
Omar Ajoue 2024-04-04 10:28:35 +01:00 committed by GitHub
parent f6ce81e7da
commit bc6575afbb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 37 additions and 3 deletions

View file

@ -7,7 +7,7 @@ import { useWorkflowsStore } from '@/stores/workflows.store';
import { useUIStore } from '@/stores/ui.store'; import { useUIStore } from '@/stores/ui.store';
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers'; import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import type { IPinData, IRunData, Workflow } from 'n8n-workflow'; import { ExpressionError, type IPinData, type IRunData, type Workflow } from 'n8n-workflow';
vi.mock('@/stores/n8nRoot.store', () => ({ vi.mock('@/stores/n8nRoot.store', () => ({
useRootStore: vi.fn().mockReturnValue({ pushConnectionActive: true }), useRootStore: vi.fn().mockReturnValue({ pushConnectionActive: true }),
@ -281,5 +281,34 @@ describe('useRunWorkflow({ router })', () => {
expect(result.startNodeNames).toContain('node1'); expect(result.startNodeNames).toContain('node1');
expect(result.runData).toBeUndefined(); expect(result.runData).toBeUndefined();
}); });
it('should rerun failed parent nodes, adding them to the returned list of start nodes and not adding their result to runData', () => {
const { consolidateRunDataAndStartNodes } = useRunWorkflow({ router });
const directParentNodes = ['node1'];
const runData = {
node1: [
{
error: new ExpressionError('error'),
},
],
} as unknown as IRunData;
const workflowMock = {
getParentNodes: vi.fn().mockReturnValue([]),
nodes: {
node1: { disabled: false },
node2: { disabled: false },
},
} as unknown as Workflow;
const result = consolidateRunDataAndStartNodes(
directParentNodes,
runData,
undefined,
workflowMock,
);
expect(result.startNodeNames).toContain('node1');
expect(result.runData).toEqual(undefined);
});
}); });
}); });

View file

@ -349,14 +349,19 @@ export function useRunWorkflow(useRunWorkflowOpts: { router: ReturnType<typeof u
parentNodes.push(directParentNode); parentNodes.push(directParentNode);
for (const parentNode of parentNodes) { for (const parentNode of parentNodes) {
if (!runData[parentNode]?.length && !pinData?.[parentNode]?.length) { // We want to execute nodes that don't have run data neither pin data
// in addition, if a node failed we want to execute it again
if (
(!runData[parentNode]?.length && !pinData?.[parentNode]?.length) ||
runData[parentNode]?.[0]?.error !== undefined
) {
// When we hit a node which has no data we stop and set it // When we hit a node which has no data we stop and set it
// as a start node the execution from and then go on with other // as a start node the execution from and then go on with other
// direct input nodes // direct input nodes
startNodeNames.push(parentNode); startNodeNames.push(parentNode);
break; break;
} }
if (runData[parentNode]) { if (runData[parentNode] && !runData[parentNode]?.[0]?.error) {
newRunData[parentNode] = runData[parentNode]?.slice(0, 1); newRunData[parentNode] = runData[parentNode]?.slice(0, 1);
} }
} }