mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 10:02:05 +00:00
fix(core): Fix task runner logging to browser console (#15111)
This commit is contained in:
@@ -1,7 +1,14 @@
|
|||||||
|
import { isObject } from 'lodash';
|
||||||
import set from 'lodash/set';
|
import set from 'lodash/set';
|
||||||
import { DateTime, Duration, Interval } from 'luxon';
|
import { DateTime, Duration, Interval } from 'luxon';
|
||||||
import { getAdditionalKeys } from 'n8n-core';
|
import { getAdditionalKeys } from 'n8n-core';
|
||||||
import { WorkflowDataProxy, Workflow, ObservableObject, Expression } from 'n8n-workflow';
|
import {
|
||||||
|
WorkflowDataProxy,
|
||||||
|
Workflow,
|
||||||
|
ObservableObject,
|
||||||
|
Expression,
|
||||||
|
jsonStringify,
|
||||||
|
} from 'n8n-workflow';
|
||||||
import type {
|
import type {
|
||||||
CodeExecutionMode,
|
CodeExecutionMode,
|
||||||
IWorkflowExecuteAdditionalData,
|
IWorkflowExecuteAdditionalData,
|
||||||
@@ -19,7 +26,6 @@ import type {
|
|||||||
IWorkflowDataProxyData,
|
IWorkflowDataProxyData,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import * as a from 'node:assert';
|
import * as a from 'node:assert';
|
||||||
import { inspect } from 'node:util';
|
|
||||||
import { type Context, createContext, runInContext } from 'node:vm';
|
import { type Context, createContext, runInContext } from 'node:vm';
|
||||||
|
|
||||||
import type { MainConfig } from '@/config/main-config';
|
import type { MainConfig } from '@/config/main-config';
|
||||||
@@ -498,7 +504,11 @@ export class JsTaskRunner extends TaskRunner {
|
|||||||
// Send log output back to the main process. It will take care of forwarding
|
// Send log output back to the main process. It will take care of forwarding
|
||||||
// it to the UI or printing to console.
|
// it to the UI or printing to console.
|
||||||
log: (...args: unknown[]) => {
|
log: (...args: unknown[]) => {
|
||||||
const formattedLogArgs = args.map((arg) => inspect(arg));
|
const formattedLogArgs = args.map((arg) => {
|
||||||
|
if (isObject(arg) && '__isExecutionContext' in arg) return '[[ExecutionContext]]';
|
||||||
|
if (typeof arg === 'string') return `'${arg}'`;
|
||||||
|
return jsonStringify(arg, { replaceCircularRefs: true });
|
||||||
|
});
|
||||||
void this.makeRpcCall(taskId, 'logNodeOutput', formattedLogArgs);
|
void this.makeRpcCall(taskId, 'logNodeOutput', formattedLogArgs);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -521,7 +531,7 @@ export class JsTaskRunner extends TaskRunner {
|
|||||||
additionalProperties: Record<string, unknown> = {},
|
additionalProperties: Record<string, unknown> = {},
|
||||||
): Context {
|
): Context {
|
||||||
return createContext({
|
return createContext({
|
||||||
[inspect.custom]: () => '[[ExecutionContext]]',
|
__isExecutionContext: true,
|
||||||
require: this.requireResolver,
|
require: this.requireResolver,
|
||||||
module: {},
|
module: {},
|
||||||
console: this.buildCustomConsole(taskId),
|
console: this.buildCustomConsole(taskId),
|
||||||
|
|||||||
@@ -226,4 +226,37 @@ describe('ExecuteContext', () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('logNodeOutput', () => {
|
||||||
|
it('when in manual mode, should parse JSON', () => {
|
||||||
|
const json = '{"key": "value", "nested": {"foo": "bar"}}';
|
||||||
|
const expectedParsedObject = { key: 'value', nested: { foo: 'bar' } };
|
||||||
|
const numberArg = 42;
|
||||||
|
const stringArg = 'hello world!';
|
||||||
|
|
||||||
|
const manualModeContext = new ExecuteContext(
|
||||||
|
workflow,
|
||||||
|
node,
|
||||||
|
additionalData,
|
||||||
|
'manual',
|
||||||
|
runExecutionData,
|
||||||
|
runIndex,
|
||||||
|
connectionInputData,
|
||||||
|
inputData,
|
||||||
|
executeData,
|
||||||
|
[closeFn],
|
||||||
|
abortSignal,
|
||||||
|
);
|
||||||
|
|
||||||
|
const sendMessageSpy = jest.spyOn(manualModeContext, 'sendMessageToUI');
|
||||||
|
|
||||||
|
manualModeContext.logNodeOutput(json, numberArg, stringArg);
|
||||||
|
|
||||||
|
expect(sendMessageSpy.mock.calls[0][0]).toEqual(expectedParsedObject);
|
||||||
|
expect(sendMessageSpy.mock.calls[0][1]).toBe(numberArg);
|
||||||
|
expect(sendMessageSpy.mock.calls[0][2]).toBe(stringArg);
|
||||||
|
|
||||||
|
sendMessageSpy.mockRestore();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import {
|
|||||||
ApplicationError,
|
ApplicationError,
|
||||||
createDeferredPromise,
|
createDeferredPromise,
|
||||||
createEnvProviderState,
|
createEnvProviderState,
|
||||||
|
jsonParse,
|
||||||
NodeConnectionTypes,
|
NodeConnectionTypes,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
@@ -183,7 +184,10 @@ export class ExecuteContext extends BaseExecuteContext implements IExecuteFuncti
|
|||||||
|
|
||||||
logNodeOutput(...args: unknown[]): void {
|
logNodeOutput(...args: unknown[]): void {
|
||||||
if (this.mode === 'manual') {
|
if (this.mode === 'manual') {
|
||||||
this.sendMessageToUI(...args);
|
const parsedLogArgs = args.map((arg) =>
|
||||||
|
typeof arg === 'string' ? jsonParse(arg, { fallbackValue: arg }) : arg,
|
||||||
|
);
|
||||||
|
this.sendMessageToUI(...parsedLogArgs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user