mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-02 07:01:30 -08:00
fix(core): Recover successful data-less executions (#12720)
This commit is contained in:
parent
97e651433b
commit
a39b8bd32b
|
@ -3,6 +3,7 @@ import { stringify } from 'flatted';
|
||||||
import { mock } from 'jest-mock-extended';
|
import { mock } from 'jest-mock-extended';
|
||||||
import { InstanceSettings } from 'n8n-core';
|
import { InstanceSettings } from 'n8n-core';
|
||||||
import { randomInt } from 'n8n-workflow';
|
import { randomInt } from 'n8n-workflow';
|
||||||
|
import assert from 'node:assert';
|
||||||
|
|
||||||
import { ARTIFICIAL_TASK_DATA } from '@/constants';
|
import { ARTIFICIAL_TASK_DATA } from '@/constants';
|
||||||
import { ExecutionRepository } from '@/databases/repositories/execution.repository';
|
import { ExecutionRepository } from '@/databases/repositories/execution.repository';
|
||||||
|
@ -127,12 +128,15 @@ describe('ExecutionRecoveryService', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('if leader, with 1+ messages', () => {
|
describe('if leader, with 1+ messages', () => {
|
||||||
test('should return `null` if execution succeeded', async () => {
|
test('for successful dataful execution, should return `null`', async () => {
|
||||||
/**
|
/**
|
||||||
* Arrange
|
* Arrange
|
||||||
*/
|
*/
|
||||||
const workflow = await createWorkflow();
|
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');
|
const messages = setupMessages(execution.id, 'Some workflow');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -170,7 +174,38 @@ describe('ExecutionRecoveryService', () => {
|
||||||
expect(amendedExecution).toBeNull();
|
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
|
* Arrange
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -73,7 +73,7 @@ export class ExecutionRecoveryService {
|
||||||
unflattenData: true,
|
unflattenData: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!execution || execution.status === 'success') return null;
|
if (!execution || (execution.status === 'success' && execution.data)) return null;
|
||||||
|
|
||||||
const runExecutionData = execution.data ?? { resultData: { runData: {} } };
|
const runExecutionData = execution.data ?? { resultData: { runData: {} } };
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue