【NestJS】异常 & 过滤器

异常

基础异常类

NestJS 中 HttpException 为基础异常类。

我们可以在应用程序中通过 new HttpException(响应体, HTTP 状态码) 创建该异常并抛出。

这里的 HTTP 状态码 可以从 NestJS 内置的 HttpStatus 枚举中获取。

@Get()
findAll() {
    throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
}

现在当客户端调用这个路由函数时,响应如下所示:

{
    "statusCode": 403,
    "message": "Forbidden"
}

内置 HTTP 异常

NestJS 内置了一系列继承自 HttpException 的异常:

  1. BadRequestException
  2. UnauthorizedException
  3. NotFoundException
  4. ForbiddenException
  5. NotAcceptableException
  6. RequestTimeoutException
  7. ConflictException
  8. GoneException
  9. PayloadTooLargeException
  10. UnsupportedMediaTypeException
  11. UnprocessableException
  12. InternalServerErrorException
  13. NotImplementedException
  14. BadGatewayException
  15. ServiceUnavailableException
  16. GatewayTimeoutException



异常过滤器

异常过滤器可捕获异常,并向前端返回友好的响应内容。

NestJS 内置了一个全局过滤器,该过滤器会处理 HttpException (及其子类) 的异常。当这个异常无法被识别时 (不是 HttpException (及其子类) 的异常),用户会收到一下 JSON 响应:

{
    "statusCode": 500,
    "message": "Internal server error"
}

创建过滤器

可以使用 Nest-Cli 的命令 nest g filter XXX / nest g f XXX 创建一个过滤器的基础框架。

import {
    ArgumentsHost,
    Catch,
    ExceptionFilter,
    HttpException,
} from '@nestjs/common';
import { Request, Response } from 'express';

@Catch(HttpException) // 捕获 HttpException 错误;  如果 @Catch() 里面没有参数, 则捕获所有错误
export class HttpExceptionFilter implements ExceptionFilter {
    catch(exception: HttpException, host: ArgumentsHost) {
        const ctx = host.switchToHttp(); // 获取上下文
        const status = exception.getStatus(); // 获取状态码

        // 通过上下文获取请求和响应
        const request = ctx.getRequest<Request>();
        const response = ctx.getResponse<Response>();

        // 自定义响应
        response.status(status).json({
            status,
            method: request.method,
            path: request.url,
            data: exception.message || exception.name,
            time: new Date().toLocaleString(),
        });
    }
}

上例的 @Catch(XXX) 中,XXX 为该过滤器需要捕获的异常。如果不写,则表示捕获所有异常。@Catch() 可以传递多个参数,参数之间用 , 隔开。


注册过滤器

NestJS 中有 [全局]、[控制器]、[路由] 过滤器

Global 过滤器

使用 app.useGlobalFilters() 注册;全局过滤器只能有一个

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { HttpExceptionFilter } from './filters/http-exception.filter';

async function bootstrap() {
    const app = await NestFactory.create(AppModule);
    app.useGlobalFilters(new HttpExceptionFilter()); // 注册 Global 过滤器
    await app.listen(3000);
}
bootstrap();

Controller 过滤器

使用 @UseFilters() 注册;多个过滤器之间用 , 隔开

@Controller('project')
@UseFilters(new HttpExceptionFilter()) // 注册 Controller 过滤器
export class ProjectController {}

Route 过滤器

使用 @UseFilters 注册;多个过滤器之间用 , 隔开

@Post()
@UseFilters(new HttpExceptionFilter()) // 注册 Route 过滤器
create(@Body() createCatDto: CreateCatDto) {}

过滤器的使用

因为 Nest 可以轻松地在整个模块中重复使用同一类的实例,所以注册过滤器时不使用实例注册 而直接使用类注册可以减少内存的开销。

@Post()
@UseFilters(HttpExceptionFilter) // 直接使用类进行注册
create(@Body() createCatDto: CreateCatDto) {}

你可能感兴趣的:(NestJS,笔记,javascript,前端,开发语言,node.js)