Nestjs(五)异常处理方式(异常过滤器)

一、简介

  • 异常过滤器 - 官方文档

  • 创建异常过滤器 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
          });
      }
    }
    

二、局部支持异常处理

image.png

  • 某个接口

    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 {
          
           }
    

猜你喜欢

转载自blog.csdn.net/zz00008888/article/details/135020475