前言
在我们上篇文章配置好了NestJS不同的环境下面加载不同的配置文件之后,这篇文章我们来研究以下NestJS中的全局异常拦截。
第一步:
新建两个文件,分别命名为http.exception.filter.ts和base.exception.filter.ts。他们分别代表统一异常处理和全局异常处理。
当base.exception.filter的Catch方法接受的参数为空的时候,默认的就是捕获全部异常
import { FastifyReply, FastifyRequest } from "fastify";
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpStatus,
ServiceUnavailableException,
HttpException,
} from '@nestjs/common';
@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
catch(exception: Error, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<FastifyReply>();
const request = ctx.getRequest<FastifyRequest>();
request.log.error(exception)
// 非 HTTP 标准异常的处理。
response.status(HttpStatus.SERVICE_UNAVAILABLE).send({
statusCode: HttpStatus.SERVICE_UNAVAILABLE,
timestamp: new Date().toISOString(),
path: request.url,
message: new ServiceUnavailableException().getResponse(),
});
}
}
http.exception.filter.ts => Catch 的参数为 HttpException 将只捕获 HTTP 相关的异常错误
import { FastifyReply, FastifyRequest } from "fastify";
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
} from '@nestjs/common';
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<FastifyReply>();
const request = ctx.getRequest<FastifyRequest>();
const status = exception.getStatus();
response.status(status).send({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
message: exception.getResponse(),
});
}
}
第二步
在 main.ts 文件中添加 useGlobalFilters 全局过滤器:
// 异常过滤器
app.useGlobalFilters(new AllExceptionsFilter(), new HttpExceptionFilter());
这里要注意,我们是先将全局的异常进行拦截处理之后,我们再来处理HTTP的异常。否则的话,不存在的异常捕获逻辑会出现混乱。
我们现在在User模块下面添加这样的一个接口,这个接口一定会报错。现在我们访问这个接口:
@Get('findError')
@Version([VERSION_NEUTRAL, '1'])
findError() {
const a: any = {}
console.log(a.b.c)
return this.userService.findAll();
}