From cc44af9243457a5dfa904c205ad5428f793104b4 Mon Sep 17 00:00:00 2001 From: Michael Auerswald Date: Thu, 8 Jun 2023 09:17:59 +0200 Subject: [PATCH] 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 --- packages/cli/src/Server.ts | 2 +- packages/cli/src/WaitTracker.ts | 25 ++++++++++++++++--- .../editor-ui/src/mixins/executionsHelpers.ts | 4 +-- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/packages/cli/src/Server.ts b/packages/cli/src/Server.ts index 521b8de00c..398180af18 100644 --- a/packages/cli/src/Server.ts +++ b/packages/cli/src/Server.ts @@ -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), diff --git a/packages/cli/src/WaitTracker.ts b/packages/cli/src/WaitTracker.ts index 91e1051b35..0b9902b3b2 100644 --- a/packages/cli/src/WaitTracker.ts +++ b/packages/cli/src/WaitTracker.ts @@ -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!'); diff --git a/packages/editor-ui/src/mixins/executionsHelpers.ts b/packages/editor-ui/src/mixins/executionsHelpers.ts index 7d2ab2a578..c5e417a8ef 100644 --- a/packages/editor-ui/src/mixins/executionsHelpers.ts +++ b/packages/editor-ui/src/mixins/executionsHelpers.ts @@ -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';