From 67cd4ecf20abc1bdba1ecb2dfe9c9e3e74aa04e0 Mon Sep 17 00:00:00 2001 From: Tomi Turtiainen <10324676+tomi@users.noreply.github.com> Date: Mon, 30 Dec 2024 15:32:14 +0200 Subject: [PATCH] Use util.inspect instead of JSON.parse --- .../__tests__/js-task-runner.test.ts | 21 +++++++++++++++++++ .../src/js-task-runner/js-task-runner.ts | 4 +++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/packages/@n8n/task-runner/src/js-task-runner/__tests__/js-task-runner.test.ts b/packages/@n8n/task-runner/src/js-task-runner/__tests__/js-task-runner.test.ts index 8ccff746ab0c8..d51c0a3a87aaf 100644 --- a/packages/@n8n/task-runner/src/js-task-runner/__tests__/js-task-runner.test.ts +++ b/packages/@n8n/task-runner/src/js-task-runner/__tests__/js-task-runner.test.ts @@ -190,6 +190,27 @@ describe('JsTaskRunner', () => { }), ).resolves.toBeDefined(); }); + + it('should log the context object as [[ExecutionContext]]', async () => { + const rpcCallSpy = jest.spyOn(defaultTaskRunner, 'makeRpcCall').mockResolvedValue(undefined); + + const task = newTaskWithSettings({ + code: ` + console.log(this); + return {json: {}} + `, + nodeMode: 'runOnceForAllItems', + }); + + await execTaskWithParams({ + task, + taskData: newDataRequestResponse([wrapIntoJson({})]), + }); + + expect(rpcCallSpy).toHaveBeenCalledWith(task.taskId, 'logNodeOutput', [ + '[[ExecutionContext]]', + ]); + }); }); describe('built-in methods and variables available in the context', () => { diff --git a/packages/@n8n/task-runner/src/js-task-runner/js-task-runner.ts b/packages/@n8n/task-runner/src/js-task-runner/js-task-runner.ts index 3d5469678bf11..07019f4cf0cc5 100644 --- a/packages/@n8n/task-runner/src/js-task-runner/js-task-runner.ts +++ b/packages/@n8n/task-runner/src/js-task-runner/js-task-runner.ts @@ -18,6 +18,7 @@ import type { IWorkflowDataProxyData, } from 'n8n-workflow'; import * as a from 'node:assert'; +import { inspect } from 'node:util'; import { runInNewContext, type Context } from 'node:vm'; import type { MainConfig } from '@/config/main-config'; @@ -438,7 +439,7 @@ export class JsTaskRunner extends TaskRunner { private buildCustomConsole(taskId: string): CustomConsole { const stringifyArg = (arg: unknown) => { try { - return typeof arg === 'object' && arg !== null ? JSON.stringify(arg) : arg; + return typeof arg === 'object' && arg !== null ? inspect(arg) : arg; } catch (e) { const error = ensureError(e); console.warn('Failed to stringify console.log argument:', error.message); @@ -479,6 +480,7 @@ export class JsTaskRunner extends TaskRunner { additionalProperties: Record = {}, ): Context { const context: Context = { + [inspect.custom]: () => '[[ExecutionContext]]', require: this.requireResolver, module: {}, console: this.buildCustomConsole(taskId),