@UseFilters

@UseFilters 用于设置异常过滤器,作用于控制器 MethodDecorator & ClassDecorator:

import { Controller, UseFilters } from '@nestjs/common';
@Controller('user')
@UseFilters(MyHttpExceptionFilter, OtherFilter)
export class UserController {
  @Get()
  @UseFilters(MyHttpExceptionFilter, OtherFilter)
  async fn() {}

如果需要全局过滤器:

import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { ConfigService } from '@nestjs/config';
import { AppModule } from './app.module';
import { text } from 'body-parser';
import * as xmlparser from 'express-xml-bodyparser';
import * as cookieParser from 'cookie-parser';
import { join } from 'path';
import { GlobalExceptionFilter } from './common/filter/global.filter';
async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);
  app.enableCors();
  app.use(cookieParser());
  app.use(text());
  app.use(xmlparser());
  app.useStaticAssets(join(process.cwd(), 'public'));
  app.useGlobalFilters(new GlobalExceptionFilter());      // 设置全局异常过滤器
  const configService = app.get(ConfigService);
  process.title = configService.get<string>('TITLE');
  const PORT = configService.get<number>('PORT');
  await app.listen(PORT);
  console.log(`server running at port:${PORT}`);
bootstrap();

这种情况下,过滤器不能使用依赖注入,怎么办呢?只能手动获取了:

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);
  const configService = app.get(ConfigService);
  app.useGlobalFilters(new GlobalExceptionFilter(configService));
  process.title = configService.get<string>('TITLE');

BaseExceptionFilter

import { ExceptionFilter, Catch, ArgumentsHost, HttpException, HttpStatus } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';
import { Request, Response } from 'express';
@Catch(Error)
export class GlobalExceptionFilter extends BaseExceptionFilter implements ExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    if (exception instanceof HttpException) {
        return this.catchHttpException(exception, host);
    if (exception instanceof Error) {
        return this.catchError(exception, host);
    // return super.catch(exception, host) // 使用 @Catch() 捕获全部抛出可能运行到此,但是如果不注入 HttpAdapterHost 依赖则 BaseExceptionFilter 会抛异常
  catchError(exception: Error, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    response
      .status(HttpStatus.BAD_GATEWAY)
      .json({
        error: 'ERROR!'
  catchHttpException(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,

全局过滤器可以继承基本过滤器,需要手动注入 HttpAdapterHost 依赖:

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const { httpAdapter } = app.get(HttpAdapterHost);
  app.useGlobalFilters(new AllExceptionsFilter(httpAdapter));
  await app.listen(3000);
bootstrap();

异常过滤器只能捕获控制器内抛出的异常,不能捕获拦截器和中间件抛出的异常,这些异常会导致整个应用程序停止运行,因此要小心使用。
通常,对于 Observable 进行 pipe 或者 subscribe 操作时,需要处理好 catchError操作 和 error(e) 回调。

@UseInterceptors

@UseInterceptors 用于设置拦截器,作用于控制器 MethodDecorator & ClassDecorator:

import { Controller, UseInterceptors } from '@nestjs/common';
@Controller('user')
@UseFilters(A, B)
export class UserController {
  @Get()
  @UseInterceptors(C)
  async fn() {}

也可以设置全局拦截器:

app.useGlobalInterceptors(A, B, C);