热搜:前端 nest neovim nvim

Nest框架中的异常 => 异常过滤器

lxf2023-06-16 03:10:07

Nest框架中有内置的异常层,负责处理整个应用程序中的所有抛出的异常。

基础异常

Nest提供了一个内置的 HttpException 类,它从 @nestjs/common 包中导入。

import {
  Controller,
  Get,
  HttpException,
  HttpStatus,
  Post,
  Redirect,
} from '@nestjs/common';
import { AppService } from '../app.service';
import { UserService } from './user.service';
@Controller('user')
export class UserController {
  constructor(
    private readonly appService: AppService,
    private readonly userService: UserService,
  ) {}

  @Get('/v1')
  getRoute() {
  
    // 写法一、
    throw new HttpException('异常信息', HttpStatus.FORBIDDEN);
    
    // 写法二、
    throw new HttpException({ 
        status: HttpStatus.FORBIDDEN, 
        error: '异常信息',
    }, HttpStatus.FORBIDDEN);
  }
}

结果:

Nest框架中的异常 => 异常过滤器 HttpException 构造函数有两个必要的参数来决定响应:

  • response 参数定义 JSON 响应体。它可以是 string 或 object
  • status参数定义HTTP状态代码。

默认情况下,JSON 响应主体包含两个属性:

  • statusCode:默认为 status 参数中提供的 HTTP 状态代码
  • message:基于状态的 HTTP 错误的简短描述

异常过滤器

作用:将捕获到的异常转化为我们期望的格式并返回给客户端

快速创建过滤器文件

// 创建一个名为 http-exception 的过滤器文件
nest g filter httpException

创建的初始文件,如下:

// http-exception.filter.ts
import { ArgumentsHost, Catch, ExceptionFilter } from '@nestjs/common';

@Catch()
export class HttpExceptionFilter<T> implements ExceptionFilter {
  catch(exception: T, host: ArgumentsHost) {}
}

下面创建了一个异常过滤器,它负责捕获作为HttpException类实例的异常,并为它们设置自定义响应逻辑

import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
// 底层调用express中的 Request和Response方法
import { Request, Response } from 'express';

// 表示该异常过滤器只会捕获 `HttpException` 类型的异常
@Catch(HttpException)
// 定义 HttpExceptionFilter 类,实现 ExceptionFilter 接口
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    // 获取当前的 `Response` 和 `Request` 对象
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();
    // 获取异常的 HTTP 状态码
    const status = exception.getStatus();

    response
      .status(status)
      .json({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}

@Catch() 装饰器绑定所需的元数据到异常过滤器上。

@Catch() 可以传递多个参数,可以通过逗号分隔来为多个类型的异常设置过滤器

绑定过滤器

将创建的过滤器方法,绑定到控制器的方法上

@UseFilters() 装饰器:新建并注册过滤器

@Post()
@UseFilters(new HttpExceptionFilter())
async create(@Body() createCatDto: CreateCatDto) {
  throw new ForbiddenException();
}

全局过滤器

在入口文件中,使用useGlobalFilters()方法,来创建全局范围的过滤器

// main.ts
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalFilters(new HttpExceptionFilter());
  await app.listen(3000);
}
bootstrap();

捕获所有异常

捕获每一个未处理的异常,将 @Catch() 装饰器的参数列表设为空

import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpException,
  HttpStatus,
} from '@nestjs/common';

@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const request = ctx.getRequest();

    const status =
      exception instanceof HttpException
        ? exception.getStatus()
        : HttpStatus.INTERNAL_SERVER_ERROR;

    response.status(status).json({
      statusCode: status,
      timestamp: new Date().toISOString(),
      path: request.url,
    });
  }
}
本网站是一个以CSS、JavaScript、Vue、HTML为核心的前端开发技术网站。我们致力于为广大前端开发者提供专业、全面、实用的前端开发知识和技术支持。 在本网站中,您可以学习到最新的前端开发技术,了解前端开发的最新趋势和最佳实践。我们提供丰富的教程和案例,让您可以快速掌握前端开发的核心技术和流程。 本网站还提供一系列实用的工具和插件,帮助您更加高效地进行前端开发工作。我们提供的工具和插件都经过精心设计和优化,可以帮助您节省时间和精力,提升开发效率。 除此之外,本网站还拥有一个活跃的社区,您可以在社区中与其他前端开发者交流技术、分享经验、解决问题。我们相信,社区的力量可以帮助您更好地成长和进步。 在本网站中,您可以找到您需要的一切前端开发资源,让您成为一名更加优秀的前端开发者。欢迎您加入我们的大家庭,一起探索前端开发的无限可能!