Skip to content

Commit

Permalink
fix(core): Recover successful data-less executions (#12720)
Browse files Browse the repository at this point in the history
  • Loading branch information
ivov authored Jan 22, 2025
1 parent 97e6514 commit a39b8bd
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { stringify } from 'flatted';
import { mock } from 'jest-mock-extended';
import { InstanceSettings } from 'n8n-core';
import { randomInt } from 'n8n-workflow';
import assert from 'node:assert';

import { ARTIFICIAL_TASK_DATA } from '@/constants';
import { ExecutionRepository } from '@/databases/repositories/execution.repository';
Expand Down Expand Up @@ -127,12 +128,15 @@ describe('ExecutionRecoveryService', () => {
});

describe('if leader, with 1+ messages', () => {
test('should return `null` if execution succeeded', async () => {
test('for successful dataful execution, should return `null`', async () => {
/**
* Arrange
*/
const workflow = await createWorkflow();
const execution = await createExecution({ status: 'success' }, workflow);
const execution = await createExecution(
{ status: 'success', data: stringify({ runData: { foo: 'bar' } }) },
workflow,
);
const messages = setupMessages(execution.id, 'Some workflow');

/**
Expand Down Expand Up @@ -170,7 +174,38 @@ describe('ExecutionRecoveryService', () => {
expect(amendedExecution).toBeNull();
});

test('should update `status`, `stoppedAt` and `data` if last node did not finish', async () => {
test('for successful dataless execution, should update `status`, `stoppedAt` and `data`', async () => {
/**
* Arrange
*/
const workflow = await createWorkflow();
const execution = await createExecution(
{
status: 'success',
data: stringify(undefined), // saved execution but likely crashed while saving high-volume data
},
workflow,
);
const messages = setupMessages(execution.id, 'Some workflow');

/**
* Act
*/
const amendedExecution = await executionRecoveryService.recoverFromLogs(
execution.id,
messages,
);

/**
* Assert
*/
assert(amendedExecution);
expect(amendedExecution.stoppedAt).not.toBe(execution.stoppedAt);
expect(amendedExecution.data).toEqual({ resultData: { runData: {} } });
expect(amendedExecution.status).toBe('crashed');
});

test('for running execution, should update `status`, `stoppedAt` and `data` if last node did not finish', async () => {
/**
* Arrange
*/
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/executions/execution-recovery.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export class ExecutionRecoveryService {
unflattenData: true,
});

if (!execution || execution.status === 'success') return null;
if (!execution || (execution.status === 'success' && execution.data)) return null;

const runExecutionData = execution.data ?? { resultData: { runData: {} } };

Expand Down

0 comments on commit a39b8bd

Please sign in to comment.