From 61579760295a960360d1bdf054b294dd462372f5 Mon Sep 17 00:00:00 2001 From: tone Date: Mon, 15 Dec 2025 22:24:32 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=BB=9F=E4=B8=80=E5=90=8E=E7=AB=AF?= =?UTF-8?q?=E5=93=8D=E5=BA=94=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/exceptions/business.exception.ts | 22 ++++++++++ .../filters/global.exceptions.filter.ts | 43 +++++++++++++++++++ .../interceptors/response.interceptor.ts | 3 +- apps/backend/src/main.ts | 8 ++-- 4 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 apps/backend/src/common/exceptions/business.exception.ts create mode 100644 apps/backend/src/common/filters/global.exceptions.filter.ts diff --git a/apps/backend/src/common/exceptions/business.exception.ts b/apps/backend/src/common/exceptions/business.exception.ts new file mode 100644 index 0000000..5f614da --- /dev/null +++ b/apps/backend/src/common/exceptions/business.exception.ts @@ -0,0 +1,22 @@ +import { HttpStatus } from '@nestjs/common'; + +export class BusinessException { + + public statusCode: HttpStatus; + public message: string; + public code: number; + public data: any; + + constructor(args: { + statusCode?: HttpStatus, + message?: string, + code?: number, + data?: any, + }) { + const { statusCode, message, code, data } = args; + this.statusCode = statusCode || HttpStatus.BAD_REQUEST; + this.message = message || '请求错误'; + this.code = code || -1; + this.data = data || null; + } +} \ No newline at end of file diff --git a/apps/backend/src/common/filters/global.exceptions.filter.ts b/apps/backend/src/common/filters/global.exceptions.filter.ts new file mode 100644 index 0000000..ececc3c --- /dev/null +++ b/apps/backend/src/common/filters/global.exceptions.filter.ts @@ -0,0 +1,43 @@ +import { ArgumentsHost, ExceptionFilter, HttpException, HttpStatus, Logger } from "@nestjs/common"; +import { Request, Response } from "express"; +import { BusinessException } from "../exceptions/business.exception"; + +export class GlobalExceptionsFilter implements ExceptionFilter { + catch(exception: any, host: ArgumentsHost) { + const ctx = host.switchToHttp(); + const response = ctx.getResponse(); + const request = ctx.getRequest(); + + let statusCode = HttpStatus.INTERNAL_SERVER_ERROR; + let errorResponse = { + success: false, + message: '服务器内部错误', + code: -1, + data: null as any, + }; + + if (exception instanceof BusinessException) { + statusCode = exception.statusCode; + const { message, code, data } = exception; + errorResponse = { + ...errorResponse, + message, code, data, + } + } else if (exception instanceof HttpException) { + // 当HttpException传入类型为string时,响应data为null,message为传入的string + // 其他请况(object/number),响应为传入数据,message为HttpException的错误码 + statusCode = exception.getStatus(); + const response = exception.getResponse() as Record; + if (response.message) { + errorResponse.message = response.message; + } else { + errorResponse.message = '请求失败'; + errorResponse.data = response; + } + } else { + Logger.warn(exception, request.path); + } + + response.status(statusCode).json(errorResponse); + } +} \ No newline at end of file diff --git a/apps/backend/src/common/interceptors/response.interceptor.ts b/apps/backend/src/common/interceptors/response.interceptor.ts index 62f0c51..207724e 100644 --- a/apps/backend/src/common/interceptors/response.interceptor.ts +++ b/apps/backend/src/common/interceptors/response.interceptor.ts @@ -15,7 +15,8 @@ export class ResponseInterceptor implements NestInterceptor { ): Observable | Promise> { return next.handle().pipe( map((data) => ({ - statusCode: 200, + success: true, + code: 0, message: '请求成功', data, })), diff --git a/apps/backend/src/main.ts b/apps/backend/src/main.ts index 745eb1c..1d63bec 100644 --- a/apps/backend/src/main.ts +++ b/apps/backend/src/main.ts @@ -2,6 +2,7 @@ import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { BadRequestException, ValidationPipe } from '@nestjs/common'; import { ResponseInterceptor } from './common/interceptors/response.interceptor'; +import { GlobalExceptionsFilter } from './common/filters/global.exceptions.filter'; async function bootstrap() { const app = await NestFactory.create(AppModule); @@ -18,15 +19,12 @@ async function bootstrap() { ? Object.values(error.constraints)[0] : '验证失败'; - throw new BadRequestException({ - message: firstConstraint, - error: 'Bad Request', - statusCode: 400, - }); + throw new BadRequestException(firstConstraint); }, }), ); app.useGlobalInterceptors(new ResponseInterceptor()); + app.useGlobalFilters(new GlobalExceptionsFilter()); await app.listen(process.env.PORT ?? 3001); } bootstrap();