一、简介
- 异常过滤器 - 官方文档
- 创建异常过滤器
http-exception.filter.ts
文件
$ nest g f http-exception
// 这是创建后的文件初始内容 import { ArgumentsHost, Catch, ExceptionFilter } from '@nestjs/common'; @Catch() export class HttpExceptionFilter<T> implements ExceptionFilter { catch(exception: T, host: ArgumentsHost) { // 这里就是拦截到的异常,需要处理并抛出给到前台方便直观看到问题... // 输出拦截到的错误异常 console.log(exception) } }
- 做下小改造,上面初始化的只会在
node
控制台输出,现在改造成将这个异常抛出到接口返回,前端接口就能看得到:
import { ArgumentsHost, Catch, ExceptionFilter, HttpException } from '@nestjs/common'; // 如果不引用,可能会导致类型关联错误 import { Response, Request } from 'express'; // 捕获 HttpException 错误; 如果 @Catch() 里面没有参数, 则捕获所有错误 // 可以支持多个 @Catch(HttpException, xxx, xxx) // 支持的内置异常列表文档:https://docs.nestjs.cn/10/exceptionfilters?id=%e5%86%85%e7%bd%aehttp%e5%bc%82%e5%b8%b8 @Catch(HttpException) export class HttpExceptionFilter<T> implements ExceptionFilter { // exception:当前正在处理的异常对象 // host:传递给原始处理程序的一个包装(Response/Request)引用参数 catch(exception: HttpException, host: ArgumentsHost) { // 获取上下文 const ctx = host.switchToHttp(); // 响应对象,跟接口中 @Response @Res 取到的一样 const response = ctx.getResponse<Response>(); // 请求对象,跟接口中 @Request @Req 取到的一样 const request = ctx.getRequest<Request>(); // 异常状态 const status = exception.getStatus(); // 抛出错误日志 response .status(status) .json({ dzm: '测试字段', statusCode: status, timestamp: new Date().toISOString(), path: request.url }); } }
二、局部支持异常处理
- 某个接口
import { Controller, Get, Body, Query, Post, Param, Request, Req, Res, Redirect, HttpCode, HttpException, HttpStatus, UseFilters } from '@nestjs/common'; import { UserService } from './user.service'; // 这里也需要引入 import { HttpExceptionFilter } from 'src/http-exception.filter'; @Controller('user') export class UserController { constructor(private readonly userService: UserService) { } @Get('/dzm') // 添加上过滤器 @UseFilters(new HttpExceptionFilter()) getDzm(@Req() req: any, @Res() res: any): any { // 故意抛出异常进行测试 throw new HttpException('Forbidden', HttpStatus.FORBIDDEN) res.send(req.query) } }
- 某个控制器下的所有接口
import { Controller, Get, Body, Query, Post, Param, Request, Req, Res, Redirect, HttpCode, HttpException, HttpStatus, UseFilters } from '@nestjs/common'; import { UserService } from './user.service'; import { HttpExceptionFilter } from 'src/http-exception.filter'; @Controller('user') @UseFilters(new HttpExceptionFilter()) export class UserController { constructor(private readonly userService: UserService) { } @Get('/dzm') getDzm(@Req() req: any, @Res() res: any): any { // 故意抛出异常进行测试 throw new HttpException('Forbidden', HttpStatus.FORBIDDEN) res.send(req.query) } }
三、全局异常处理
- 方式一:
main.ts
,无法注入依赖
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { HttpExceptionFilter } from './http-exception.filter'; async function bootstrap() { const app = await NestFactory.create(AppModule); // 全局注册异常过滤器 app.useGlobalFilters(new HttpExceptionFilter()) await app.listen(3000); } bootstrap();
- 方式二:
app.module.ts
,支持注入依赖
import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { UserModule } from './user/user.module'; import { LoginModule } from './login/login.module'; import { APP_FILTER } from '@nestjs/core'; import { HttpExceptionFilter } from './http-exception.filter'; @Module({ imports: [UserModule, LoginModule], controllers: [AppController], providers: [ AppService, // 这样注册即可,效果一样,可以根据需要使用此技术添加任意数量的过滤器 { provide: APP_FILTER, useClass: HttpExceptionFilter, }, ], }) export class AppModule { }