From 3ff902feb909620b3cc4e886e26891645c4f1b46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Ovejero?= Date: Thu, 2 Jan 2025 17:48:39 +0100 Subject: [PATCH] refactor(core): Hide stack trace for warning-level errors (#12411) --- .../src/errors/feature-not-licensed.error.ts | 1 + packages/core/src/error-reporter.ts | 5 +++- packages/core/test/error-reporter.test.ts | 26 +++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/errors/feature-not-licensed.error.ts b/packages/cli/src/errors/feature-not-licensed.error.ts index a61015f2e4..aa53655154 100644 --- a/packages/cli/src/errors/feature-not-licensed.error.ts +++ b/packages/cli/src/errors/feature-not-licensed.error.ts @@ -6,6 +6,7 @@ export class FeatureNotLicensedError extends ApplicationError { constructor(feature: (typeof LICENSE_FEATURES)[keyof typeof LICENSE_FEATURES]) { super( `Your license does not allow for ${feature}. To enable ${feature}, please upgrade to a license that supports this feature.`, + { level: 'warning' }, ); } } diff --git a/packages/core/src/error-reporter.ts b/packages/core/src/error-reporter.ts index cd20dc9f9a..910b309270 100644 --- a/packages/core/src/error-reporter.ts +++ b/packages/core/src/error-reporter.ts @@ -29,7 +29,10 @@ export class ErrorReporter { const context = executionId ? ` (execution ${executionId})` : ''; do { - const msg = [e.message + context, e.stack ? `\n${e.stack}\n` : ''].join(''); + const msg = [ + e.message + context, + e instanceof ApplicationError && e.level === 'error' && e.stack ? `\n${e.stack}\n` : '', + ].join(''); const meta = e instanceof ApplicationError ? e.extra : undefined; this.logger.error(msg, meta); e = e.cause as Error; diff --git a/packages/core/test/error-reporter.test.ts b/packages/core/test/error-reporter.test.ts index 7cd94fdb4b..9edc27f15c 100644 --- a/packages/core/test/error-reporter.test.ts +++ b/packages/core/test/error-reporter.test.ts @@ -5,6 +5,7 @@ import { mock } from 'jest-mock-extended'; import { ApplicationError } from 'n8n-workflow'; import { ErrorReporter } from '@/error-reporter'; +import type { Logger } from '@/logging/logger'; jest.mock('@sentry/node', () => ({ init: jest.fn(), @@ -101,4 +102,29 @@ describe('ErrorReporter', () => { expect(result).toBeNull(); }); }); + + describe('error', () => { + let error: ApplicationError; + let logger: Logger; + let errorReporter: ErrorReporter; + const metadata = undefined; + + beforeEach(() => { + error = new ApplicationError('Test error'); + logger = mock(); + errorReporter = new ErrorReporter(logger); + }); + + it('should include stack trace for error-level `ApplicationError`', () => { + error.level = 'error'; + errorReporter.error(error); + expect(logger.error).toHaveBeenCalledWith(`Test error\n${error.stack}\n`, metadata); + }); + + it('should exclude stack trace for warning-level `ApplicationError`', () => { + error.level = 'warning'; + errorReporter.error(error); + expect(logger.error).toHaveBeenCalledWith('Test error', metadata); + }); + }); });