NestJS框架中的异常过滤器(Exception Filters)是一种用于全局处理应用程序中未被捕获异常的结构化方法。 它为你的应用程序中的异常提供了一种中心化的捕获和处理方法。这样一来,你就可以确保应用程序中的所有异常都得到了处理,并且客户端也能够收到有用的错误响应。本文将详细介绍异常过滤器的用法和实现方式。
前置知识
在介绍异常过滤器之前,需要了解以下知识:
- 异常(Errors)
- 异步编程(Asynchronous programming)
- HTTP 响应(Response)
异常过滤器简介
异常过滤器是一个处理未被捕获异常的结构化方法。当应用程序中出现未处理的异常时,异常过滤器会提供一个中央点的处理方法,并将异常转换为友好的HTTP响应格式返回给客户端。异常过滤器能够处理同步和异步代码中的所有异常。使用异常过滤器可以改进应用程序的可读性、可维护性和可靠性。
异常过滤器的实现
要创建一个异常过滤器,你可以创建一个类并实现 ExceptionFilter
接口。此接口定义了一个带有两个参数的 catch
方法,以处理异常:
import { Catch, ExceptionFilter, HttpException } from '@nestjs/common';
import { Request, Response } from 'express';
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, response: Response) {
const status = exception.getStatus();
const message = exception.message;
response.status(status).json({
statusCode: status,
message,
});
}
}
在上面的例子中,我们定义了一个 HttpExceptionFilter
的类来处理HTTP异常。@Catch(HttpException)
装饰器用于注入 HttpException
类的实例。HttpException
类是一个基于 HTTP 状态码的异常类,它包含一个 getStatus()
方法,用于获取异常的状态码。
在 catch
方法中,我们调用了 response.status(status).json()
方法,该方法将转换为HTTP响应并将其发送回客户端。我们还从异常对象中获取了状态码和消息,并将它们转换为 HTTP 响应中的 JSON 数据。
使用全局异常过滤器
要在整个应用程序中使用异常过滤器,你可以将其注册为全局异常过滤器。
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { HttpExceptionFilter } from './common/filters/http-exception.filter';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalFilters(new HttpExceptionFilter());
await app.listen(3000);
}
bootstrap();
在上面的代码中,我们首先引入了 HttpExceptionFilter
,然后将其注册为全局异常过滤器。使用 app.useGlobalFilters()
方法将异常过滤器添加到应用程序中。
特定路由和控制器中使用异常过滤器
你还可以在特定的路由和控制器中使用异常过滤器,如下面的代码所示:
import { Controller, Get } from '@nestjs/common';
import { HttpException } from '@nestjs/common/exceptions/http.exception';
import { HttpExceptionFilter } from './common/filters/http-exception.filter';
@Controller()
export class AppController {
@Get()
findAll() {
throw new HttpException('Forbidden', 403);
}
@Get('error')
@UseFilters(new HttpExceptionFilter())
throwError() {
throw new HttpException('Forbidden', 403);
}
}
在上面的代码中,我们在 findAll
方法中抛出了一个 HTTP 异常。这个方法不使用过滤器,所以当异常被抛出时,它将返回一个默认的 HTTP 错误响应。