diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/utils/compute-pg-graphql-error.util.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/utils/compute-pg-graphql-error.util.ts index c25e3a0dc..b3f0e23f2 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/utils/compute-pg-graphql-error.util.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/utils/compute-pg-graphql-error.util.ts @@ -4,8 +4,16 @@ import { InternalServerErrorException, } from '@nestjs/common'; +export type PgGraphQLConfig = { + atMost: number; +}; + interface PgGraphQLErrorMapping { - [key: string]: (command: string, objectName: string) => HttpException; + [key: string]: ( + command: string, + objectName: string, + pgGraphqlConfig: PgGraphQLConfig, + ) => HttpException; } const pgGraphQLCommandMapping = { @@ -15,13 +23,15 @@ const pgGraphQLCommandMapping = { }; const pgGraphQLErrorMapping: PgGraphQLErrorMapping = { - 'delete impacts too many records': (command, objectName) => + 'delete impacts too many records': (_, objectName, pgGraphqlConfig) => new BadRequestException( - `Cannot ${ - pgGraphQLCommandMapping[command] ?? command - } ${objectName} because it impacts too many records.`, + `Cannot delete ${objectName} because it impacts too many records (more than ${pgGraphqlConfig?.atMost}).`, ), - 'duplicate key value violates unique constraint': (command, objectName) => + 'update impacts too many records': (_, objectName, pgGraphqlConfig) => + new BadRequestException( + `Cannot update ${objectName} because it impacts too many records (more than ${pgGraphqlConfig?.atMost}).`, + ), + 'duplicate key value violates unique constraint': (command, objectName, _) => new BadRequestException( `Cannot ${ pgGraphQLCommandMapping[command] ?? command @@ -33,6 +43,7 @@ export const computePgGraphQLError = ( command: string, objectName: string, errors: any[], + pgGraphqlConfig: PgGraphQLConfig, ) => { const error = errors[0]; const errorMessage = error?.message; @@ -46,7 +57,7 @@ export const computePgGraphQLError = ( : null; if (mappedError) { - return mappedError(command, objectName); + return mappedError(command, objectName, pgGraphqlConfig); } return new InternalServerErrorException( diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service.ts index 0aa209253..49b4944e5 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service.ts @@ -56,7 +56,10 @@ import { PGGraphQLMutation, PGGraphQLResult, } from './interfaces/pg-graphql.interface'; -import { computePgGraphQLError } from './utils/compute-pg-graphql-error.util'; +import { + PgGraphQLConfig, + computePgGraphQLError, +} from './utils/compute-pg-graphql-error.util'; @Injectable() export class WorkspaceQueryRunnerService { @@ -374,7 +377,7 @@ export class WorkspaceQueryRunnerService { const { userId, workspaceId, objectMetadataItem } = options; assertMutationNotOnRemoteObject(objectMetadataItem); - assertIsValidUuid(args.data.id); + args.filter?.id?.in?.forEach((id) => assertIsValidUuid(id)); const maximumRecordAffected = this.environmentService.get( 'MUTATION_MAXIMUM_RECORD_AFFECTED', @@ -613,6 +616,11 @@ export class WorkspaceQueryRunnerService { command, objectMetadataItem.nameSingular, errors, + { + atMost: this.environmentService.get( + 'MUTATION_MAXIMUM_RECORD_AFFECTED', + ), + } satisfies PgGraphQLConfig, ); throw error;