feat(core): Add execution runData recovery and status field (#5112)
* adds ExecutionEvents view modal to ExecutionList * fix time rendering and remove wf column * checks for unfinished executions and fails them * prevent re-setting stoppedAt for execution * some cleanup / manually create rundata after crash * quicksave * remove Threads lib, log worker rewrite * cleanup comment * fix sentry destination return value * test for tests... * run tests with single worker * fix tests * remove console log * add endpoint for execution data recovery * lint cleanup and some refactoring * fix accidental recursion * remove cyclic imports * add rundata recovery to Workflowrunner * remove comments * cleanup and refactor * adds a status field to executions * setExecutionStatus on queued worker * fix onWorkflowPostExecute * set waiting from worker * get crashed status into frontend * remove comment * merge fix * cleanup * catch empty rundata in recovery * refactor IExecutionsSummary and inject nodeExecution Errors * reduce default event log size to 10mb from 100mb * add per node execution status * lint fix * merge and lint fix * phrasing change * improve preview rendering and messaging * remove debug * Improve partial rundata recovery * fix labels * fix line through * send manual rundata to ui at crash * some type and msg push fixes * improve recovered item rendering in preview * update workflowStatistics on recover * merge fix * review fixes * merge fix * notify eventbus when ui is back up * add a small timeout to make sure the UI is back up * increase reconnect timeout to 30s * adjust recover timeout and ui connection lost msg * do not stop execution in editor after x reconnects * add executionRecovered push event * fix recovered connection not green * remove reconnect toast and merge existing rundata * merge editor and recovered data for own mode
This commit is contained in:
committed by
GitHub
parent
3a9c257f55
commit
d143f3f2ec
@@ -4,11 +4,13 @@
|
||||
import { snakeCase } from 'change-case';
|
||||
import { BinaryDataManager } from 'n8n-core';
|
||||
import type {
|
||||
ExecutionStatus,
|
||||
INodesGraphResult,
|
||||
INodeTypes,
|
||||
IRun,
|
||||
ITelemetryTrackProperties,
|
||||
IWorkflowBase,
|
||||
WorkflowExecuteMode,
|
||||
} from 'n8n-workflow';
|
||||
import { TelemetryHelpers } from 'n8n-workflow';
|
||||
import { get as pslGet } from 'psl';
|
||||
@@ -26,6 +28,7 @@ import { RoleService } from './role/role.service';
|
||||
import { eventBus } from './eventbus';
|
||||
import type { User } from '@db/entities/User';
|
||||
import { N8N_VERSION } from '@/constants';
|
||||
import * as Db from '@/Db';
|
||||
|
||||
function userToPayload(user: User): {
|
||||
userId: string;
|
||||
@@ -220,6 +223,7 @@ export class InternalHooksClass implements IInternalHooksClass {
|
||||
data: IWorkflowExecutionDataProcess,
|
||||
): Promise<void> {
|
||||
void Promise.all([
|
||||
Db.collections.Execution.update(executionId, { status: 'running' }),
|
||||
eventBus.sendWorkflowEvent({
|
||||
eventName: 'n8n.workflow.started',
|
||||
payload: {
|
||||
@@ -233,6 +237,24 @@ export class InternalHooksClass implements IInternalHooksClass {
|
||||
]);
|
||||
}
|
||||
|
||||
async onWorkflowCrashed(
|
||||
executionId: string,
|
||||
executionMode: WorkflowExecuteMode,
|
||||
workflowData?: IWorkflowBase,
|
||||
): Promise<void> {
|
||||
void Promise.all([
|
||||
eventBus.sendWorkflowEvent({
|
||||
eventName: 'n8n.workflow.crashed',
|
||||
payload: {
|
||||
executionId,
|
||||
isManual: executionMode === 'manual',
|
||||
workflowId: workflowData?.id?.toString(),
|
||||
workflowName: workflowData?.name,
|
||||
},
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
async onWorkflowPostExecute(
|
||||
executionId: string,
|
||||
workflow: IWorkflowBase,
|
||||
@@ -315,6 +337,7 @@ export class InternalHooksClass implements IInternalHooksClass {
|
||||
user_id: userId,
|
||||
workflow_id: workflow.id,
|
||||
status: properties.success ? 'success' : 'failed',
|
||||
executionStatus: runData?.status ?? 'unknown',
|
||||
error_message: properties.error_message as string,
|
||||
error_node_type: properties.error_node_type,
|
||||
node_graph_string: properties.node_graph_string as string,
|
||||
@@ -363,6 +386,21 @@ export class InternalHooksClass implements IInternalHooksClass {
|
||||
}
|
||||
}
|
||||
|
||||
let executionStatus: ExecutionStatus;
|
||||
if (runData?.status === 'crashed') {
|
||||
executionStatus = 'crashed';
|
||||
} else if (runData?.status === 'waiting' || runData?.data?.waitTill) {
|
||||
executionStatus = 'waiting';
|
||||
} else {
|
||||
executionStatus = properties.success ? 'success' : 'failed';
|
||||
}
|
||||
|
||||
promises.push(
|
||||
Db.collections.Execution.update(executionId, {
|
||||
status: executionStatus,
|
||||
}) as unknown as Promise<void>,
|
||||
);
|
||||
|
||||
promises.push(
|
||||
properties.success
|
||||
? eventBus.sendWorkflowEvent({
|
||||
|
||||
Reference in New Issue
Block a user