From 5ab3eeb8304df9a82144eabe3fe74cae31fdb9fd Mon Sep 17 00:00:00 2001 From: Felipe <60716370+Felipeness@users.noreply.github.com> Date: Mon, 9 Mar 2026 12:41:15 -0300 Subject: [PATCH] fix: throw clear error on invalid LOG_LEVELS (#18495) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #18356 ## Summary Setting `LOG_LEVELS=debug,info,error,warn` crashes with `TypeError: logLevels.map is not a function` because `CastToLogLevelArray` silently returns `undefined` for invalid levels. Now it throws a clear error message listing the invalid levels and valid options: ``` Invalid log level(s): info. Valid levels are: log, error, warn, debug, verbose ``` ## Changes - Throw descriptive `Error` when invalid log levels are provided instead of returning `undefined` - Updated tests to verify the error message ## Test plan - [x] All 8 existing tests passing - [x] `"toto"` → throws `Invalid log level(s): toto. Valid levels are: log, error, warn, debug, verbose` - [x] `"verbose,error,toto"` → throws listing only `toto` as invalid - [x] Valid levels (`log,error,warn,debug,verbose`) continue working as before --- .../cast-to-log-level-array.decorator.spec.ts | 20 +++++++++---------- .../cast-to-log-level-array.decorator.ts | 14 +++++++++---- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/packages/twenty-server/src/engine/core-modules/twenty-config/decorators/__tests__/cast-to-log-level-array.decorator.spec.ts b/packages/twenty-server/src/engine/core-modules/twenty-config/decorators/__tests__/cast-to-log-level-array.decorator.spec.ts index 4cd656dff4..25e9d53a57 100644 --- a/packages/twenty-server/src/engine/core-modules/twenty-config/decorators/__tests__/cast-to-log-level-array.decorator.spec.ts +++ b/packages/twenty-server/src/engine/core-modules/twenty-config/decorators/__tests__/cast-to-log-level-array.decorator.spec.ts @@ -50,17 +50,17 @@ describe('CastToLogLevelArray Decorator', () => { ]); }); - it('should cast "toto" to undefined', () => { - const transformedClass = plainToClass(TestClass, { logLevels: 'toto' }); - - expect(transformedClass.logLevels).toBeUndefined(); + it('should throw on invalid level "toto" with clear error message', () => { + expect(() => plainToClass(TestClass, { logLevels: 'toto' })).toThrow( + 'Invalid log level(s): toto. Valid levels are: log, error, warn, debug, verbose', + ); }); - it('should cast "verbose,error,toto" to undefined', () => { - const transformedClass = plainToClass(TestClass, { - logLevels: 'verbose,error,toto', - }); - - expect(transformedClass.logLevels).toBeUndefined(); + it('should throw on "verbose,error,toto" listing only invalid levels', () => { + expect(() => + plainToClass(TestClass, { logLevels: 'verbose,error,toto' }), + ).toThrow( + 'Invalid log level(s): toto. Valid levels are: log, error, warn, debug, verbose', + ); }); }); diff --git a/packages/twenty-server/src/engine/core-modules/twenty-config/decorators/cast-to-log-level-array.decorator.ts b/packages/twenty-server/src/engine/core-modules/twenty-config/decorators/cast-to-log-level-array.decorator.ts index bf3b14906d..489db3b4cd 100644 --- a/packages/twenty-server/src/engine/core-modules/twenty-config/decorators/cast-to-log-level-array.decorator.ts +++ b/packages/twenty-server/src/engine/core-modules/twenty-config/decorators/cast-to-log-level-array.decorator.ts @@ -1,5 +1,7 @@ import { Transform } from 'class-transformer'; +const VALID_LOG_LEVELS = ['log', 'error', 'warn', 'debug', 'verbose']; + export const CastToLogLevelArray = () => Transform(({ value }: { value: string }) => toLogLevelArray(value)); @@ -7,13 +9,17 @@ export const CastToLogLevelArray = () => const toLogLevelArray = (value: any) => { if (typeof value === 'string') { const rawLogLevels = value.split(',').map((level) => level.trim()); - const isInvalid = rawLogLevels.some( - (level) => !['log', 'error', 'warn', 'debug', 'verbose'].includes(level), + const invalidLevels = rawLogLevels.filter( + (level) => !VALID_LOG_LEVELS.includes(level), ); - if (!isInvalid) { - return rawLogLevels; + if (invalidLevels.length > 0) { + throw new Error( + `Invalid log level(s): ${invalidLevels.join(', ')}. Valid levels are: ${VALID_LOG_LEVELS.join(', ')}`, + ); } + + return rawLogLevels; } return undefined;