Fix query runner throwing 500 when pg_graphql detects unique constraint (#5323)
## Context Since pg_graphql does not return specific error/exception, we have to map the error message and throw validation errors when needed This PR adds a check on unicity constraint error returned by pg_graphql when we are trying to insert duplicate records and returns a 400 instead of being handled by the exceptionHandler as a 500.
This commit is contained in:
@ -8,10 +8,24 @@ interface PgGraphQLErrorMapping {
|
|||||||
[key: string]: (command: string, objectName: string) => HttpException;
|
[key: string]: (command: string, objectName: string) => HttpException;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pgGraphQLCommandMapping = {
|
||||||
|
insertInto: 'insert',
|
||||||
|
update: 'update',
|
||||||
|
deleteFrom: 'delete',
|
||||||
|
};
|
||||||
|
|
||||||
const pgGraphQLErrorMapping: PgGraphQLErrorMapping = {
|
const pgGraphQLErrorMapping: PgGraphQLErrorMapping = {
|
||||||
'delete impacts too many records': (command, objectName) =>
|
'delete impacts too many records': (command, objectName) =>
|
||||||
new BadRequestException(
|
new BadRequestException(
|
||||||
`Cannot ${command} ${objectName} because it impacts too many records.`,
|
`Cannot ${
|
||||||
|
pgGraphQLCommandMapping[command] ?? command
|
||||||
|
} ${objectName} because it impacts too many records.`,
|
||||||
|
),
|
||||||
|
'duplicate key value violates unique constraint': (command, objectName) =>
|
||||||
|
new BadRequestException(
|
||||||
|
`Cannot ${
|
||||||
|
pgGraphQLCommandMapping[command] ?? command
|
||||||
|
} ${objectName} because it violates a uniqueness constraint.`,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -22,7 +36,14 @@ export const computePgGraphQLError = (
|
|||||||
) => {
|
) => {
|
||||||
const error = errors[0];
|
const error = errors[0];
|
||||||
const errorMessage = error?.message;
|
const errorMessage = error?.message;
|
||||||
const mappedError = pgGraphQLErrorMapping[errorMessage];
|
|
||||||
|
const mappedErrorKey = Object.keys(pgGraphQLErrorMapping).find(
|
||||||
|
(key) => errorMessage?.startsWith(key),
|
||||||
|
);
|
||||||
|
|
||||||
|
const mappedError = mappedErrorKey
|
||||||
|
? pgGraphQLErrorMapping[mappedErrorKey]
|
||||||
|
: null;
|
||||||
|
|
||||||
if (mappedError) {
|
if (mappedError) {
|
||||||
return mappedError(command, objectName);
|
return mappedError(command, objectName);
|
||||||
|
|||||||
@ -599,13 +599,6 @@ export class WorkspaceQueryRunnerService {
|
|||||||
const result = graphqlResult?.[0]?.resolve?.data?.[entityKey];
|
const result = graphqlResult?.[0]?.resolve?.data?.[entityKey];
|
||||||
const errors = graphqlResult?.[0]?.resolve?.errors;
|
const errors = graphqlResult?.[0]?.resolve?.errors;
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
this.logger.log(
|
|
||||||
`No result found for ${entityKey}, graphqlResult: ` +
|
|
||||||
JSON.stringify(graphqlResult, null, 3),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
result &&
|
result &&
|
||||||
['update', 'deleteFrom'].includes(command) &&
|
['update', 'deleteFrom'].includes(command) &&
|
||||||
|
|||||||
Reference in New Issue
Block a user