Cast typeorm QueryFailedError to BadRequestException for the rest api (#12217)

This commit is contained in:
martmull
2025-05-23 17:00:45 +02:00
committed by GitHub
parent 362d540aac
commit 88b967dfb8
3 changed files with 37 additions and 8 deletions

View File

@ -10,6 +10,7 @@ import {
BillingExceptionCode,
} from 'src/engine/core-modules/billing/billing.exception';
import { HttpExceptionHandlerService } from 'src/engine/core-modules/exception-handler/http-exception-handler.service';
import { CustomException } from 'src/utils/custom-exception';
@Catch(BillingException, Stripe.errors.StripeError)
export class BillingRestApiExceptionFilter implements ExceptionFilter {
@ -30,7 +31,7 @@ export class BillingRestApiExceptionFilter implements ExceptionFilter {
code: BillingExceptionCode.BILLING_STRIPE_ERROR,
message: exception.message,
name: 'StripeError',
},
} as CustomException,
response,
400,
);

View File

@ -1,14 +1,14 @@
import { Inject, Injectable, Scope } from '@nestjs/common';
import { BadRequestException, Inject, Injectable, Scope } from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { Response } from 'express';
import { QueryFailedError } from 'typeorm';
import { ExceptionHandlerUser } from 'src/engine/core-modules/exception-handler/interfaces/exception-handler-user.interface';
import { ExceptionHandlerWorkspace } from 'src/engine/core-modules/exception-handler/interfaces/exception-handler-workspace.interface';
import { ExceptionHandlerService } from 'src/engine/core-modules/exception-handler/exception-handler.service';
import { handleException } from 'src/engine/utils/global-exception-handler.util';
import { CustomException } from 'src/utils/custom-exception';
interface RequestAndParams {
request: Request | null;
@ -25,7 +25,7 @@ export class HttpExceptionHandlerService {
) {}
handleError = (
exception: CustomException,
exception: Error,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
response: Response<any, Record<string, any>>,
@ -37,11 +37,20 @@ export class HttpExceptionHandlerService {
): Response<any, Record<string, any>> | undefined => {
const params = this.request?.params;
if (params?.workspaceId)
if (params?.workspaceId) {
workspace = { ...workspace, id: params.workspaceId };
if (params?.userId) user = { ...user, id: params.userId };
}
const statusCode = errorCode || 500;
if (params?.userId) {
user = { ...user, id: params.userId };
}
let statusCode = errorCode || 500;
if (exception instanceof QueryFailedError) {
exception = new BadRequestException(exception.message);
statusCode = 400;
}
handleException({
exception,
@ -53,7 +62,7 @@ export class HttpExceptionHandlerService {
return response.status(statusCode).send({
statusCode,
error: exception.name || 'Bad Request',
error: exception.name || 'BadRequestException',
messages: [exception?.message],
});
};

View File

@ -193,4 +193,23 @@ describe('Core REST API Create One endpoint', () => {
expect(res.body.error).toBe('BadRequestException');
});
});
it('should return a BadRequestException when trying to create an opportunity with an invalid enum', async () => {
const requestBody = {
stage: 'INVALID_ENUM_VALUE',
};
await makeRestAPIRequest({
method: 'post',
path: `/opportunities`,
body: requestBody,
})
.expect(400)
.expect((res) => {
expect(res.body.messages[0]).toMatch(
/invalid input value for enum workspace_[a-z0-9]+\.opportunity_stage_enum: "INVALID_ENUM_VALUE"/,
);
expect(res.body.error).toBe('BadRequestException');
});
});
});