From b31845b7baed808814313adf9919294344f1e3d9 Mon Sep 17 00:00:00 2001 From: Paul Rastoin <45004772+prastoin@users.noreply.github.com> Date: Tue, 24 Jun 2025 18:30:56 +0200 Subject: [PATCH] Fix resolver-validation validation snake trap (#12850) # Introduction This PR might have a lot of impact on tested validation Avoid catching programmatically thrown error --------- Co-authored-by: Charles Bochet --- .../graphql/pipes/resolver-validation.pipe.ts | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/packages/twenty-server/src/engine/core-modules/graphql/pipes/resolver-validation.pipe.ts b/packages/twenty-server/src/engine/core-modules/graphql/pipes/resolver-validation.pipe.ts index 295fc3867..b54e35bbf 100644 --- a/packages/twenty-server/src/engine/core-modules/graphql/pipes/resolver-validation.pipe.ts +++ b/packages/twenty-server/src/engine/core-modules/graphql/pipes/resolver-validation.pipe.ts @@ -10,6 +10,16 @@ import { ValidationError, validate } from 'class-validator'; import { UserInputError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util'; +const safeClassValidatorValidateWrapper = async ( + object: object, +): Promise => { + try { + return await validate(object); + } catch (error) { + return []; + } +}; + @Injectable() export class ResolverValidationPipe implements PipeTransform { async transform(value: unknown, metadata: ArgumentMetadata) { @@ -20,21 +30,16 @@ export class ResolverValidationPipe implements PipeTransform { } const object = plainToInstance(metatype, value); + const errors = await safeClassValidatorValidateWrapper(object); - try { - const errors = await validate(object); - - if (errors.length > 0) { - const errorMessage = this.formatErrorMessage(errors); - - throw new UserInputError(errorMessage); - } - } catch (error) { - // If the element is not a class, we can't validate it + if (errors.length === 0) { + // TODO shouldn't we return the object here ? As transpilation could bring mutations return value; } - return value; + const errorMessage = this.formatErrorMessage(errors); + + throw new UserInputError(errorMessage); } // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -50,6 +55,10 @@ export class ResolverValidationPipe implements PipeTransform { return Object.values(error.constraints); } + if (error.children) { + return this.formatErrorMessage(error.children); + } + return []; });