diff --git a/packages/nodes-base/nodes/Set/v2/helpers/utils.ts b/packages/nodes-base/nodes/Set/v2/helpers/utils.ts index 378e817857..7b4fbf5e33 100644 --- a/packages/nodes-base/nodes/Set/v2/helpers/utils.ts +++ b/packages/nodes-base/nodes/Set/v2/helpers/utils.ts @@ -9,6 +9,7 @@ import { ApplicationError, NodeOperationError, deepCopy, + getValueDescription, jsonParse, validateFieldType, } from 'n8n-workflow'; @@ -184,7 +185,7 @@ export const validateEntry = ( } else { throw new NodeOperationError( node, - `'${name}' expects a ${type} but we got '${String(value)}' [item ${itemIndex}]`, + `'${name}' expects a ${type} but we got ${getValueDescription(value)} [item ${itemIndex}]`, { description }, ); } diff --git a/packages/workflow/src/TypeValidation.ts b/packages/workflow/src/TypeValidation.ts index 0e8afdb494..606c3d201e 100644 --- a/packages/workflow/src/TypeValidation.ts +++ b/packages/workflow/src/TypeValidation.ts @@ -145,6 +145,16 @@ export const tryToParseObject = (value: unknown): object => { } }; +export const getValueDescription = (value: T): string => { + if (typeof value === 'object') { + if (value === null) return "'null'"; + if (Array.isArray(value)) return 'array'; + return 'object'; + } + + return `'${String(value)}'`; +}; + export const tryToParseUrl = (value: unknown): string => { if (typeof value === 'string' && !value.includes('://')) { value = `http://${value}`; @@ -196,7 +206,8 @@ export function validateFieldType( const strict = options.strict ?? false; const valueOptions = options.valueOptions ?? []; const parseStrings = options.parseStrings ?? false; - const defaultErrorMessage = `'${fieldName}' expects a ${type} but we got '${String(value)}'`; + + const defaultErrorMessage = `'${fieldName}' expects a ${type} but we got ${getValueDescription(value)}`; switch (type.toLowerCase()) { case 'string': { if (!parseStrings) return { valid: true, newValue: value }; @@ -256,7 +267,7 @@ export function validateFieldType( } catch (e) { return { valid: false, - errorMessage: `'${fieldName}' expects time (hh:mm:(:ss)) but we got '${String(value)}'.`, + errorMessage: `'${fieldName}' expects time (hh:mm:(:ss)) but we got ${getValueDescription(value)}.`, }; } } @@ -287,9 +298,9 @@ export function validateFieldType( if (!isValidOption) { return { valid: false, - errorMessage: `'${fieldName}' expects one of the following values: [${validOptions}] but we got '${String( + errorMessage: `'${fieldName}' expects one of the following values: [${validOptions}] but we got ${getValueDescription( value, - )}'`, + )}`, }; } return { valid: true, newValue: value }; diff --git a/packages/workflow/test/TypeValidation.test.ts b/packages/workflow/test/TypeValidation.test.ts index 16467f06de..1a1e99afac 100644 --- a/packages/workflow/test/TypeValidation.test.ts +++ b/packages/workflow/test/TypeValidation.test.ts @@ -1,4 +1,4 @@ -import { validateFieldType } from '@/TypeValidation'; +import { getValueDescription, validateFieldType } from '@/TypeValidation'; import { DateTime } from 'luxon'; const VALID_ISO_DATES = [ @@ -230,4 +230,15 @@ describe('Type Validation', () => { }); }); }); + describe('getValueDescription util function', () => { + it('should return correct description', () => { + expect(getValueDescription('foo')).toBe("'foo'"); + expect(getValueDescription(42)).toBe("'42'"); + expect(getValueDescription(true)).toBe("'true'"); + expect(getValueDescription(null)).toBe("'null'"); + expect(getValueDescription(undefined)).toBe("'undefined'"); + expect(getValueDescription([{}])).toBe('array'); + expect(getValueDescription({})).toBe('object'); + }); + }); });