Skip to content

Commit cc44af9

Browse files
fix(core): Allow all executions to be stopped (n8n-io#6386)
* allow all executions to be stopped and fix display issue * limit cancelation and add recover for unknown states
1 parent 28bb797 commit cc44af9

File tree

3 files changed

+25
-6
lines changed

3 files changed

+25
-6
lines changed

packages/cli/src/Server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1246,7 +1246,7 @@ export class Server extends AbstractServer {
12461246
throw new ResponseHelper.NotFoundError('Execution not found');
12471247
}
12481248

1249-
const execution = await Db.collections.Execution.findOne({
1249+
const execution = await Db.collections.Execution.exist({
12501250
where: {
12511251
id: executionId,
12521252
workflowId: In(sharedWorkflowIds),

packages/cli/src/WaitTracker.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@ import * as Db from '@/Db';
1818
import * as ResponseHelper from '@/ResponseHelper';
1919
import type {
2020
IExecutionFlattedDb,
21+
IExecutionResponse,
2122
IExecutionsStopData,
2223
IWorkflowExecutionDataProcess,
2324
} from '@/Interfaces';
2425
import { WorkflowRunner } from '@/WorkflowRunner';
2526
import { getWorkflowOwner } from '@/UserManagement/UserManagementHelper';
27+
import { recoverExecutionDataFromEventLogMessages } from './eventbus/MessageEventBus/recoverEvents';
2628

2729
@Service()
2830
export class WaitTracker {
@@ -106,12 +108,29 @@ export class WaitTracker {
106108
// Also check in database
107109
const execution = await Db.collections.Execution.findOneBy({ id: executionId });
108110

109-
if (execution === null || !execution.waitTill) {
111+
if (execution === null) {
110112
throw new Error(`The execution ID "${executionId}" could not be found.`);
111113
}
112114

113-
const fullExecutionData = ResponseHelper.unflattenExecutionData(execution);
114-
115+
if (!['new', 'unknown', 'waiting', 'running'].includes(execution.status)) {
116+
throw new Error(
117+
`Only running or waiting executions can be stopped and ${executionId} is currently ${execution.status}.`,
118+
);
119+
}
120+
let fullExecutionData: IExecutionResponse;
121+
try {
122+
fullExecutionData = ResponseHelper.unflattenExecutionData(execution);
123+
} catch (error) {
124+
// if the execution ended in an unforseen, non-cancelable state, try to recover it
125+
await recoverExecutionDataFromEventLogMessages(executionId, [], true);
126+
// find recovered data
127+
const recoveredExecution = await Db.collections.Execution.findOneBy({ id: executionId });
128+
if (recoveredExecution) {
129+
fullExecutionData = ResponseHelper.unflattenExecutionData(recoveredExecution);
130+
} else {
131+
throw new Error(`Execution ${executionId} could not be recovered or canceled.`);
132+
}
133+
}
115134
// Set in execution in DB as failed and remove waitTill time
116135
const error = new WorkflowOperationError('Workflow-Execution has been canceled!');
117136

packages/editor-ui/src/mixins/executionsHelpers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ export const executionHelpers = defineComponent({
4444
if (execution.status === 'waiting' || execution.waitTill) {
4545
status.name = 'waiting';
4646
status.label = this.$locale.baseText('executionsList.waiting');
47+
} else if (execution.status === 'canceled') {
48+
status.label = this.$locale.baseText('executionsList.canceled');
4749
} else if (
4850
execution.status === 'running' ||
4951
execution.status === 'new' ||
@@ -57,8 +59,6 @@ export const executionHelpers = defineComponent({
5759
} else if (execution.status === 'failed' || execution.status === 'crashed') {
5860
status.name = 'error';
5961
status.label = this.$locale.baseText('executionsList.error');
60-
} else if (execution.status === 'canceled') {
61-
status.label = this.$locale.baseText('executionsList.canceled');
6262
}
6363

6464
if (!execution.status) execution.status = 'unknown';

0 commit comments

Comments
 (0)