mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-11 12:57:29 -08:00
fix(core): Allow all executions to be stopped (#6386)
* allow all executions to be stopped and fix display issue * limit cancelation and add recover for unknown states
This commit is contained in:
parent
28bb797bb0
commit
cc44af9243
|
@ -1246,7 +1246,7 @@ export class Server extends AbstractServer {
|
|||
throw new ResponseHelper.NotFoundError('Execution not found');
|
||||
}
|
||||
|
||||
const execution = await Db.collections.Execution.findOne({
|
||||
const execution = await Db.collections.Execution.exist({
|
||||
where: {
|
||||
id: executionId,
|
||||
workflowId: In(sharedWorkflowIds),
|
||||
|
|
|
@ -18,11 +18,13 @@ import * as Db from '@/Db';
|
|||
import * as ResponseHelper from '@/ResponseHelper';
|
||||
import type {
|
||||
IExecutionFlattedDb,
|
||||
IExecutionResponse,
|
||||
IExecutionsStopData,
|
||||
IWorkflowExecutionDataProcess,
|
||||
} from '@/Interfaces';
|
||||
import { WorkflowRunner } from '@/WorkflowRunner';
|
||||
import { getWorkflowOwner } from '@/UserManagement/UserManagementHelper';
|
||||
import { recoverExecutionDataFromEventLogMessages } from './eventbus/MessageEventBus/recoverEvents';
|
||||
|
||||
@Service()
|
||||
export class WaitTracker {
|
||||
|
@ -106,12 +108,29 @@ export class WaitTracker {
|
|||
// Also check in database
|
||||
const execution = await Db.collections.Execution.findOneBy({ id: executionId });
|
||||
|
||||
if (execution === null || !execution.waitTill) {
|
||||
if (execution === null) {
|
||||
throw new Error(`The execution ID "${executionId}" could not be found.`);
|
||||
}
|
||||
|
||||
const fullExecutionData = ResponseHelper.unflattenExecutionData(execution);
|
||||
|
||||
if (!['new', 'unknown', 'waiting', 'running'].includes(execution.status)) {
|
||||
throw new Error(
|
||||
`Only running or waiting executions can be stopped and ${executionId} is currently ${execution.status}.`,
|
||||
);
|
||||
}
|
||||
let fullExecutionData: IExecutionResponse;
|
||||
try {
|
||||
fullExecutionData = ResponseHelper.unflattenExecutionData(execution);
|
||||
} catch (error) {
|
||||
// if the execution ended in an unforseen, non-cancelable state, try to recover it
|
||||
await recoverExecutionDataFromEventLogMessages(executionId, [], true);
|
||||
// find recovered data
|
||||
const recoveredExecution = await Db.collections.Execution.findOneBy({ id: executionId });
|
||||
if (recoveredExecution) {
|
||||
fullExecutionData = ResponseHelper.unflattenExecutionData(recoveredExecution);
|
||||
} else {
|
||||
throw new Error(`Execution ${executionId} could not be recovered or canceled.`);
|
||||
}
|
||||
}
|
||||
// Set in execution in DB as failed and remove waitTill time
|
||||
const error = new WorkflowOperationError('Workflow-Execution has been canceled!');
|
||||
|
||||
|
|
|
@ -44,6 +44,8 @@ export const executionHelpers = defineComponent({
|
|||
if (execution.status === 'waiting' || execution.waitTill) {
|
||||
status.name = 'waiting';
|
||||
status.label = this.$locale.baseText('executionsList.waiting');
|
||||
} else if (execution.status === 'canceled') {
|
||||
status.label = this.$locale.baseText('executionsList.canceled');
|
||||
} else if (
|
||||
execution.status === 'running' ||
|
||||
execution.status === 'new' ||
|
||||
|
@ -57,8 +59,6 @@ export const executionHelpers = defineComponent({
|
|||
} else if (execution.status === 'failed' || execution.status === 'crashed') {
|
||||
status.name = 'error';
|
||||
status.label = this.$locale.baseText('executionsList.error');
|
||||
} else if (execution.status === 'canceled') {
|
||||
status.label = this.$locale.baseText('executionsList.canceled');
|
||||
}
|
||||
|
||||
if (!execution.status) execution.status = 'unknown';
|
||||
|
|
Loading…
Reference in a new issue