refactor(core): Unify failed and error execution status (no-changelog) (#8943)

This commit is contained in:
Iván Ovejero 2024-03-25 17:52:07 +01:00 committed by GitHub
parent 1fb0dd4f1c
commit 69807a5efb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 36 additions and 26 deletions

View file

@ -865,7 +865,7 @@ async function executeWorkflow(
mode: 'integrated', mode: 'integrated',
startedAt: new Date(), startedAt: new Date(),
stoppedAt: new Date(), stoppedAt: new Date(),
status: 'failed', status: 'error',
}; };
// When failing, we might not have finished the execution // When failing, we might not have finished the execution
// Therefore, database might not contain finished errors. // Therefore, database might not contain finished errors.

View file

@ -61,7 +61,7 @@ export function generateFailedExecutionFromError(
mode, mode,
startedAt: new Date(), startedAt: new Date(),
stoppedAt: new Date(), stoppedAt: new Date(),
status: 'failed', status: 'error',
}; };
} }

View file

@ -0,0 +1,9 @@
import type { IrreversibleMigration, MigrationContext } from '@db/types';
export class RemoveFailedExecutionStatus1711018413374 implements IrreversibleMigration {
async up({ escape, runQuery }: MigrationContext) {
const executionEntity = escape.tableName('execution_entity');
await runQuery(`UPDATE ${executionEntity} SET status = 'error' WHERE status = 'failed';`);
}
}

View file

@ -52,6 +52,7 @@ import { AddWorkflowMetadata1695128658538 } from '../common/1695128658538-AddWor
import { ModifyWorkflowHistoryNodesAndConnections1695829275184 } from '../common/1695829275184-ModifyWorkflowHistoryNodesAndConnections'; import { ModifyWorkflowHistoryNodesAndConnections1695829275184 } from '../common/1695829275184-ModifyWorkflowHistoryNodesAndConnections';
import { AddGlobalAdminRole1700571993961 } from '../common/1700571993961-AddGlobalAdminRole'; import { AddGlobalAdminRole1700571993961 } from '../common/1700571993961-AddGlobalAdminRole';
import { DropRoleMapping1705429061930 } from '../common/1705429061930-DropRoleMapping'; import { DropRoleMapping1705429061930 } from '../common/1705429061930-DropRoleMapping';
import { RemoveFailedExecutionStatus1711018413374 } from '../common/1711018413374-RemoveFailedExecutionStatus';
export const mysqlMigrations: Migration[] = [ export const mysqlMigrations: Migration[] = [
InitialMigration1588157391238, InitialMigration1588157391238,
@ -107,4 +108,5 @@ export const mysqlMigrations: Migration[] = [
ModifyWorkflowHistoryNodesAndConnections1695829275184, ModifyWorkflowHistoryNodesAndConnections1695829275184,
AddGlobalAdminRole1700571993961, AddGlobalAdminRole1700571993961,
DropRoleMapping1705429061930, DropRoleMapping1705429061930,
RemoveFailedExecutionStatus1711018413374,
]; ];

View file

@ -51,6 +51,7 @@ import { MigrateToTimestampTz1694091729095 } from './1694091729095-MigrateToTime
import { ModifyWorkflowHistoryNodesAndConnections1695829275184 } from '../common/1695829275184-ModifyWorkflowHistoryNodesAndConnections'; import { ModifyWorkflowHistoryNodesAndConnections1695829275184 } from '../common/1695829275184-ModifyWorkflowHistoryNodesAndConnections';
import { AddGlobalAdminRole1700571993961 } from '../common/1700571993961-AddGlobalAdminRole'; import { AddGlobalAdminRole1700571993961 } from '../common/1700571993961-AddGlobalAdminRole';
import { DropRoleMapping1705429061930 } from '../common/1705429061930-DropRoleMapping'; import { DropRoleMapping1705429061930 } from '../common/1705429061930-DropRoleMapping';
import { RemoveFailedExecutionStatus1711018413374 } from '../common/1711018413374-RemoveFailedExecutionStatus';
export const postgresMigrations: Migration[] = [ export const postgresMigrations: Migration[] = [
InitialMigration1587669153312, InitialMigration1587669153312,
@ -105,4 +106,5 @@ export const postgresMigrations: Migration[] = [
ModifyWorkflowHistoryNodesAndConnections1695829275184, ModifyWorkflowHistoryNodesAndConnections1695829275184,
AddGlobalAdminRole1700571993961, AddGlobalAdminRole1700571993961,
DropRoleMapping1705429061930, DropRoleMapping1705429061930,
RemoveFailedExecutionStatus1711018413374,
]; ];

View file

@ -49,6 +49,7 @@ import { AddWorkflowMetadata1695128658538 } from '../common/1695128658538-AddWor
import { ModifyWorkflowHistoryNodesAndConnections1695829275184 } from '../common/1695829275184-ModifyWorkflowHistoryNodesAndConnections'; import { ModifyWorkflowHistoryNodesAndConnections1695829275184 } from '../common/1695829275184-ModifyWorkflowHistoryNodesAndConnections';
import { AddGlobalAdminRole1700571993961 } from '../common/1700571993961-AddGlobalAdminRole'; import { AddGlobalAdminRole1700571993961 } from '../common/1700571993961-AddGlobalAdminRole';
import { DropRoleMapping1705429061930 } from './1705429061930-DropRoleMapping'; import { DropRoleMapping1705429061930 } from './1705429061930-DropRoleMapping';
import { RemoveFailedExecutionStatus1711018413374 } from '../common/1711018413374-RemoveFailedExecutionStatus';
const sqliteMigrations: Migration[] = [ const sqliteMigrations: Migration[] = [
InitialMigration1588102412422, InitialMigration1588102412422,
@ -101,6 +102,7 @@ const sqliteMigrations: Migration[] = [
ModifyWorkflowHistoryNodesAndConnections1695829275184, ModifyWorkflowHistoryNodesAndConnections1695829275184,
AddGlobalAdminRole1700571993961, AddGlobalAdminRole1700571993961,
DropRoleMapping1705429061930, DropRoleMapping1705429061930,
RemoveFailedExecutionStatus1711018413374,
]; ];
export { sqliteMigrations }; export { sqliteMigrations };

View file

@ -575,7 +575,7 @@ export class ExecutionRepository extends Repository<ExecutionEntity> {
} else if (status === 'waiting') { } else if (status === 'waiting') {
condition.status = 'waiting'; condition.status = 'waiting';
} else if (status === 'error') { } else if (status === 'error') {
condition.status = In(['error', 'crashed', 'failed']); condition.status = In(['error', 'crashed']);
} }
return condition; return condition;
@ -682,7 +682,7 @@ export class ExecutionRepository extends Repository<ExecutionEntity> {
) { ) {
const where: FindOptionsWhere<ExecutionEntity> = { const where: FindOptionsWhere<ExecutionEntity> = {
id: In(activeExecutionIds), id: In(activeExecutionIds),
status: Not(In(['finished', 'stopped', 'failed', 'crashed'] as ExecutionStatus[])), status: Not(In(['finished', 'stopped', 'error', 'crashed'])),
}; };
if (filter) { if (filter) {

View file

@ -155,7 +155,7 @@ export class ExecutionDataRecoveryService {
} }
if (applyToDb) { if (applyToDb) {
const newStatus = executionEntry.status === 'failed' ? 'failed' : 'crashed'; const newStatus = executionEntry.status === 'error' ? 'error' : 'crashed';
await this.executionRepository.updateExistingExecution(executionId, { await this.executionRepository.updateExistingExecution(executionId, {
data: executionData, data: executionData,
status: newStatus, status: newStatus,

View file

@ -10,13 +10,13 @@ import { Logger } from '@/Logger';
export function determineFinalExecutionStatus(runData: IRun): ExecutionStatus { export function determineFinalExecutionStatus(runData: IRun): ExecutionStatus {
const workflowHasCrashed = runData.status === 'crashed'; const workflowHasCrashed = runData.status === 'crashed';
const workflowWasCanceled = runData.status === 'canceled'; const workflowWasCanceled = runData.status === 'canceled';
const workflowHasFailed = runData.status === 'failed'; const workflowHasFailed = runData.status === 'error';
const workflowDidSucceed = const workflowDidSucceed =
!runData.data.resultData?.error && !runData.data.resultData?.error &&
!workflowHasCrashed && !workflowHasCrashed &&
!workflowWasCanceled && !workflowWasCanceled &&
!workflowHasFailed; !workflowHasFailed;
let workflowStatusFinal: ExecutionStatus = workflowDidSucceed ? 'success' : 'failed'; let workflowStatusFinal: ExecutionStatus = workflowDidSucceed ? 'success' : 'error';
if (workflowHasCrashed) workflowStatusFinal = 'crashed'; if (workflowHasCrashed) workflowStatusFinal = 'crashed';
if (workflowWasCanceled) workflowStatusFinal = 'canceled'; if (workflowWasCanceled) workflowStatusFinal = 'canceled';
if (runData.waitTill) workflowStatusFinal = 'waiting'; if (runData.waitTill) workflowStatusFinal = 'waiting';

View file

@ -13,7 +13,7 @@ export function getStatusUsingPreviousExecutionStatusMethod(
} else if (execution.finished) { } else if (execution.finished) {
return 'success'; return 'success';
} else if (execution.stoppedAt !== null) { } else if (execution.stoppedAt !== null) {
return 'failed'; return 'error';
} else { } else {
return 'unknown'; return 'unknown';
} }

View file

@ -99,7 +99,7 @@ describe('softDeleteOnPruningCycle()', () => {
['unknown', { startedAt: now, stoppedAt: now }], ['unknown', { startedAt: now, stoppedAt: now }],
['canceled', { startedAt: now, stoppedAt: now }], ['canceled', { startedAt: now, stoppedAt: now }],
['crashed', { startedAt: now, stoppedAt: now }], ['crashed', { startedAt: now, stoppedAt: now }],
['failed', { startedAt: now, stoppedAt: now }], ['error', { startedAt: now, stoppedAt: now }],
['success', { finished: true, startedAt: now, stoppedAt: now }], ['success', { finished: true, startedAt: now, stoppedAt: now }],
])('should prune %s executions', async (status, attributes) => { ])('should prune %s executions', async (status, attributes) => {
const executions = [ const executions = [
@ -192,7 +192,7 @@ describe('softDeleteOnPruningCycle()', () => {
['unknown', { startedAt: yesterday, stoppedAt: yesterday }], ['unknown', { startedAt: yesterday, stoppedAt: yesterday }],
['canceled', { startedAt: yesterday, stoppedAt: yesterday }], ['canceled', { startedAt: yesterday, stoppedAt: yesterday }],
['crashed', { startedAt: yesterday, stoppedAt: yesterday }], ['crashed', { startedAt: yesterday, stoppedAt: yesterday }],
['failed', { startedAt: yesterday, stoppedAt: yesterday }], ['error', { startedAt: yesterday, stoppedAt: yesterday }],
['success', { finished: true, startedAt: yesterday, stoppedAt: yesterday }], ['success', { finished: true, startedAt: yesterday, stoppedAt: yesterday }],
])('should prune %s executions', async (status, attributes) => { ])('should prune %s executions', async (status, attributes) => {
const execution = await createExecution({ status, ...attributes }, workflow); const execution = await createExecution({ status, ...attributes }, workflow);

View file

@ -55,7 +55,7 @@ export async function createSuccessfulExecution(workflow: WorkflowEntity) {
*/ */
export async function createErrorExecution(workflow: WorkflowEntity) { export async function createErrorExecution(workflow: WorkflowEntity) {
return await createExecution( return await createExecution(
{ finished: false, stoppedAt: new Date(), status: 'failed' }, { finished: false, stoppedAt: new Date(), status: 'error' },
workflow, workflow,
); );
} }

View file

@ -2530,7 +2530,6 @@ const addExecutionDataFunctions = async (
taskData = taskData!; taskData = taskData!;
if (data instanceof Error) { if (data instanceof Error) {
// TODO: Or "failed", what is the difference
taskData.executionStatus = 'error'; taskData.executionStatus = 'error';
taskData.error = data; taskData.error = data;
} else { } else {

View file

@ -799,7 +799,7 @@ export default defineComponent({
} else if (execution.finished) { } else if (execution.finished) {
status = 'success'; status = 'success';
} else if (execution.stoppedAt !== null) { } else if (execution.stoppedAt !== null) {
status = 'failed'; status = 'error';
} else { } else {
status = 'unknown'; status = 'unknown';
} }
@ -825,7 +825,7 @@ export default defineComponent({
text = this.i18n.baseText('executionsList.running'); text = this.i18n.baseText('executionsList.running');
} else if (status === 'success') { } else if (status === 'success') {
text = this.i18n.baseText('executionsList.succeeded'); text = this.i18n.baseText('executionsList.succeeded');
} else if (status === 'failed') { } else if (status === 'error') {
text = this.i18n.baseText('executionsList.error'); text = this.i18n.baseText('executionsList.error');
} else { } else {
text = this.i18n.baseText('executionsList.unknown'); text = this.i18n.baseText('executionsList.unknown');
@ -841,7 +841,7 @@ export default defineComponent({
path = 'executionsList.statusWaiting'; path = 'executionsList.statusWaiting';
} else if (status === 'canceled') { } else if (status === 'canceled') {
path = 'executionsList.statusCanceled'; path = 'executionsList.statusCanceled';
} else if (['crashed', 'failed', 'success'].includes(status)) { } else if (['crashed', 'error', 'success'].includes(status)) {
if (!entry.stoppedAt) { if (!entry.stoppedAt) {
path = 'executionsList.statusTextWithoutTime'; path = 'executionsList.statusTextWithoutTime';
} else { } else {
@ -1032,7 +1032,7 @@ export default defineComponent({
font-weight: var(--font-weight-bold); font-weight: var(--font-weight-bold);
.crashed &, .crashed &,
.failed & { .error & {
color: var(--color-danger); color: var(--color-danger);
} }
@ -1143,7 +1143,7 @@ export default defineComponent({
} }
&.crashed td:first-child::before, &.crashed td:first-child::before,
&.failed td:first-child::before { &.error td:first-child::before {
background: var(--execution-card-border-error); background: var(--execution-card-border-error);
} }

View file

@ -56,7 +56,7 @@ const executionDataFactory = (): ExecutionSummary => ({
stoppedAt: faker.date.past(), stoppedAt: faker.date.past(),
workflowId: faker.number.int().toString(), workflowId: faker.number.int().toString(),
workflowName: faker.string.sample(), workflowName: faker.string.sample(),
status: faker.helpers.arrayElement(['failed', 'success']), status: faker.helpers.arrayElement(['error', 'success']),
nodeExecutionStatus: {}, nodeExecutionStatus: {},
retryOf: generateUndefinedNullOrString(), retryOf: generateUndefinedNullOrString(),
retrySuccessId: generateUndefinedNullOrString(), retrySuccessId: generateUndefinedNullOrString(),

View file

@ -285,10 +285,7 @@ export default defineComponent({
return this.workflowsStore.getWorkflowResultDataByNodeName(this.data?.name || '') || []; return this.workflowsStore.getWorkflowResultDataByNodeName(this.data?.name || '') || [];
}, },
hasIssues(): boolean { hasIssues(): boolean {
if ( if (this.nodeExecutionStatus && ['crashed', 'error'].includes(this.nodeExecutionStatus))
this.nodeExecutionStatus &&
['crashed', 'error', 'failed'].includes(this.nodeExecutionStatus)
)
return true; return true;
if (this.pinnedData.hasData.value) return false; if (this.pinnedData.hasData.value) return false;
if (this.data?.issues !== undefined && Object.keys(this.data.issues).length) { if (this.data?.issues !== undefined && Object.keys(this.data.issues).length) {

View file

@ -56,7 +56,7 @@ const executionDataFactory = (): ExecutionSummary => ({
stoppedAt: faker.date.past(), stoppedAt: faker.date.past(),
workflowId: faker.number.int().toString(), workflowId: faker.number.int().toString(),
workflowName: faker.string.sample(), workflowName: faker.string.sample(),
status: faker.helpers.arrayElement(['failed', 'success']), status: faker.helpers.arrayElement(['error', 'success']),
nodeExecutionStatus: {}, nodeExecutionStatus: {},
retryOf: generateUndefinedNullOrString(), retryOf: generateUndefinedNullOrString(),
retrySuccessId: generateUndefinedNullOrString(), retrySuccessId: generateUndefinedNullOrString(),

View file

@ -51,7 +51,7 @@ export const executionHelpers = defineComponent({
} else if (execution.status === 'success') { } else if (execution.status === 'success') {
status.name = 'success'; status.name = 'success';
status.label = this.$locale.baseText('executionsList.succeeded'); status.label = this.$locale.baseText('executionsList.succeeded');
} else if (execution.status === 'failed' || execution.status === 'crashed') { } else if (execution.status === 'error' || execution.status === 'crashed') {
status.name = 'error'; status.name = 'error';
status.label = this.$locale.baseText('executionsList.error'); status.label = this.$locale.baseText('executionsList.error');
} }

View file

@ -31,7 +31,7 @@ export const executionFilterToQueryFilter = (
queryFilter.status = ['waiting']; queryFilter.status = ['waiting'];
break; break;
case 'error': case 'error':
queryFilter.status = ['failed', 'crashed', 'error']; queryFilter.status = ['crashed', 'error'];
break; break;
case 'success': case 'success':
queryFilter.status = ['success']; queryFilter.status = ['success'];

View file

@ -2,7 +2,6 @@ export type ExecutionStatus =
| 'canceled' | 'canceled'
| 'crashed' | 'crashed'
| 'error' | 'error'
| 'failed'
| 'new' | 'new'
| 'running' | 'running'
| 'success' | 'success'