feat(core): Improve debugging of sub-workflows (#11602)

This commit is contained in:
Mutasem Aldmour
2024-11-14 23:04:43 +01:00
committed by GitHub
parent f4ca4b792f
commit fd3254d587
36 changed files with 1843 additions and 265 deletions

View File

@@ -20,7 +20,8 @@
"lint": "eslint . --quiet",
"lintfix": "eslint . --fix",
"watch": "tsc-watch -p tsconfig.build.json --onCompilationComplete \"tsc-alias -p tsconfig.build.json\"",
"test": "jest"
"test": "jest",
"test:dev": "jest --watch"
},
"files": [
"dist",

View File

@@ -39,6 +39,7 @@ import type {
BinaryHelperFunctions,
CloseFunction,
ContextType,
ExecuteWorkflowData,
FieldType,
FileSystemHelperFunctions,
FunctionsBase,
@@ -78,6 +79,7 @@ import type {
IRunExecutionData,
ITaskData,
ITaskDataConnections,
ITaskMetadata,
ITriggerFunctions,
IWebhookData,
IWebhookDescription,
@@ -109,6 +111,7 @@ import type {
ISupplyDataFunctions,
WebhookType,
SchedulingFunctions,
RelatedExecution,
} from 'n8n-workflow';
import {
NodeConnectionType,
@@ -2721,6 +2724,7 @@ const addExecutionDataFunctions = async (
sourceNodeName: string,
sourceNodeRunIndex: number,
currentNodeRunIndex: number,
metadata?: ITaskMetadata,
): Promise<void> => {
if (connectionType === NodeConnectionType.Main) {
throw new ApplicationError('Setting type is not supported for main connection', {
@@ -2746,6 +2750,7 @@ const addExecutionDataFunctions = async (
if (taskData === undefined) {
return;
}
taskData.metadata = metadata;
}
taskData = taskData!;
@@ -3622,6 +3627,12 @@ export function getExecuteFunctions(
itemIndex,
),
getExecuteData: () => executeData,
setMetadata: (metadata: ITaskMetadata): void => {
executeData.metadata = {
...(executeData.metadata ?? {}),
...metadata,
};
},
continueOnFail: () => {
return continueOnFail(node);
},
@@ -3643,23 +3654,28 @@ export function getExecuteFunctions(
workflowInfo: IExecuteWorkflowInfo,
inputData?: INodeExecutionData[],
parentCallbackManager?: CallbackManager,
): Promise<any> {
options?: {
doNotWaitToFinish?: boolean;
parentExecution?: RelatedExecution;
},
): Promise<ExecuteWorkflowData> {
return await additionalData
.executeWorkflow(workflowInfo, additionalData, {
...options,
parentWorkflowId: workflow.id?.toString(),
inputData,
parentWorkflowSettings: workflow.settings,
node,
parentCallbackManager,
})
.then(
async (result) =>
await Container.get(BinaryDataService).duplicateBinaryData(
workflow.id,
additionalData.executionId!,
result,
),
);
.then(async (result) => {
const data = await Container.get(BinaryDataService).duplicateBinaryData(
workflow.id,
additionalData.executionId!,
result.data,
);
return { ...result, data };
});
},
getContext(type: ContextType): IContextObject {
return NodeHelpers.getContext(runExecutionData, type, node);
@@ -3853,6 +3869,7 @@ export function getExecuteFunctions(
connectionType: NodeConnectionType,
currentNodeRunIndex: number,
data: INodeExecutionData[][] | ExecutionBaseError,
metadata?: ITaskMetadata,
): void {
addExecutionDataFunctions(
'output',
@@ -3864,6 +3881,7 @@ export function getExecuteFunctions(
node.name,
runIndex,
currentNodeRunIndex,
metadata,
).catch((error) => {
Logger.warn(
`There was a problem logging output data of node "${this.getNode().name}": ${
@@ -3972,7 +3990,11 @@ export function getSupplyDataFunctions(
workflowInfo: IExecuteWorkflowInfo,
inputData?: INodeExecutionData[],
parentCallbackManager?: CallbackManager,
) =>
options?: {
doNotWaitToFinish?: boolean;
parentExecution?: RelatedExecution;
},
): Promise<ExecuteWorkflowData> =>
await additionalData
.executeWorkflow(workflowInfo, additionalData, {
parentWorkflowId: workflow.id?.toString(),
@@ -3980,15 +4002,16 @@ export function getSupplyDataFunctions(
parentWorkflowSettings: workflow.settings,
node,
parentCallbackManager,
...options,
})
.then(
async (result) =>
await Container.get(BinaryDataService).duplicateBinaryData(
workflow.id,
additionalData.executionId!,
result,
),
),
.then(async (result) => {
const data = await Container.get(BinaryDataService).duplicateBinaryData(
workflow.id,
additionalData.executionId!,
result.data,
);
return { ...result, data };
}),
getNodeOutputs() {
const nodeType = workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
return NodeHelpers.getNodeOutputs(workflow, node, nodeType.description).map((output) => {
@@ -4143,6 +4166,7 @@ export function getSupplyDataFunctions(
connectionType: NodeConnectionType,
currentNodeRunIndex: number,
data: INodeExecutionData[][],
metadata?: ITaskMetadata,
): void {
addExecutionDataFunctions(
'output',
@@ -4154,6 +4178,7 @@ export function getSupplyDataFunctions(
node.name,
runIndex,
currentNodeRunIndex,
metadata,
).catch((error) => {
Logger.warn(
`There was a problem logging output data of node "${this.getNode().name}": ${

View File

@@ -408,7 +408,10 @@ export class WorkflowExecute {
let metaRunData: ITaskMetadata;
for (const nodeName of Object.keys(metadata)) {
for ([index, metaRunData] of metadata[nodeName].entries()) {
runData[nodeName][index].metadata = metaRunData;
runData[nodeName][index].metadata = {
...(runData[nodeName][index].metadata ?? {}),
...metaRunData,
};
}
}
}
@@ -1448,6 +1451,7 @@ export class WorkflowExecute {
startTime,
executionTime: new Date().getTime() - startTime,
source: !executionData.source ? [] : executionData.source.main,
metadata: executionData.metadata,
executionStatus: 'success',
};

View File

@@ -17,6 +17,7 @@ import type {
IContextObject,
ICredentialDataDecryptedObject,
ISourceData,
ITaskMetadata,
} from 'n8n-workflow';
import { ApplicationError, NodeHelpers } from 'n8n-workflow';
@@ -298,4 +299,33 @@ describe('ExecuteSingleContext', () => {
});
});
});
describe('setMetadata', () => {
it('sets metadata on execution data', () => {
const context = new ExecuteSingleContext(
workflow,
node,
additionalData,
mode,
runExecutionData,
runIndex,
connectionInputData,
inputData,
itemIndex,
executeData,
abortSignal,
);
const metadata: ITaskMetadata = {
subExecution: {
workflowId: '123',
executionId: 'xyz',
},
};
expect(context.getExecuteData().metadata?.subExecution).toEqual(undefined);
context.setMetadata(metadata);
expect(context.getExecuteData().metadata?.subExecution).toEqual(metadata.subExecution);
});
});
});

View File

@@ -13,6 +13,7 @@ import type {
ContextType,
AiEvent,
ISourceData,
ITaskMetadata,
} from 'n8n-workflow';
import {
ApplicationError,
@@ -85,6 +86,13 @@ export class ExecuteSingleContext extends NodeExecutionContext implements IExecu
this.abortSignal?.addEventListener('abort', fn);
}
setMetadata(metadata: ITaskMetadata): void {
this.executeData.metadata = {
...(this.executeData.metadata ?? {}),
...metadata,
};
}
continueOnFail() {
return continueOnFail(this.node);
}