【Nest】异常处理
2021/09/07 11:30:01
抛出异常
直接用 throw 关键字抛出即可。
import { Controller, All, HttpException, HttpStatus } from "@nestjs/common";
@Controller()
export class AppController {
@All()
findAll() {
throw new HttpException(
{
code: -1,
msg: "Forbidden",
result: false,
},
HttpStatus.BAD_REQUEST
);
}
}
异常类型
Nest 的异常类型包括基础异常类(HttpException)、自定义异常类(继承自 HttpException)和内置异常。
基础异常类
Nest 提供了一个内置的 HttpException 类,它从 @nestjs/common 包中导入。
import { HttpException } from "@nestjs/common";
自定义异常
自定义异常需要继承 HttpException 类。
- forbidden.exception.ts
import { HttpException } from "@nestjs/common";
export class ForbiddenException extends HttpException {
constructor() {
super("Forbidden", HttpStatus.FORBIDDEN);
}
}
异常过滤器
虽然基本(内置)异常过滤器可以为您自动处理许多情况,但有时您可能希望对异常层拥有完全控制权,例如,您可能要添加日志记录或基于一些动态因素使用其他 JSON 模式。 异常过滤器正是为此目的而设计的。 它们使您可以控制精确的控制流以及将响应的内容发送回客户端。
在异常过滤器中可以访问底层平台 Request 和 Response,实现更复杂的逻辑。
定义异常过滤器
- http-exception.filter.ts
import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
import { Request, Response } from 'express';
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
const status = exception.getStatus();
response
.status(status)
.json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
});
}
}
绑定过滤器
使用 @UseFilters() 装饰器来注册过滤器。
- app.controller.ts
import { Controller, All, HttpException, HttpStatus, UseFilters } from '@nestjs/common';
import { HttpExceptionFilter } from './filter/http-exception.filter'
@Controller()
export class AppController {
@All()
@UseFilters(HttpExceptionFilter)
findAll() {
throw new HttpException('normal error', HttpStatus.BAD_REQUEST);
}
}
异常过滤器的作用域
异常过滤器的作用域可以划分为不同的级别:方法范围,控制器范围或全局范围。
在方法上使用 @UseFilters() 装饰器为方法范围的过滤器。
- app.controller.ts
@All()
@UseFilters(HttpExceptionFilter)
findAll() {
throw new HttpException('normal error', HttpStatus.BAD_REQUEST);
}
在控制器类上使用 @UseFilters() 装饰器为控制器范围的过滤器。
- app.controller.ts
@Controller()
@UseFilters(HttpExceptionFilter)
export class AppController {
@All()
findAll() {
throw new HttpException('normal error', HttpStatus.BAD_REQUEST);
}
}
全局范围的过滤器需要在根 module 上绑定
- app.module.js
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalFilters(new HttpExceptionFilter());
await app.listen(3000);
}
bootstrap();