NestJS 的 Filter 过滤器处理系统全局异常

7 阅读2分钟

当一个程序运行过程中发生了异常,并且这个异常没有被捕获处理,用户就会看到一些奇怪的错误信息,这种现象对用户体验非常不好。此时,NestJS的过滤器就登场啦!过滤器可以用来捕捉未被处理的异常,然后以一种更有秩序、更友好的方式显示,极大提升了用户体验。

全局错误处理

创建一个全局过滤器来捕获所有未被处理的异常,以一致的风格返回给用户

@Catch()
export class GlobalFilter implements ExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    // 统一处理异常,返回友好的错误信息
  }
}
// 在main.ts中全局使用
app.useGlobalFilters(new GlobalFilter());

定制HTTP响应

可以用过滤器自定义服务器的响应格式。

@Catch()
export class TransformFilter implements ExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    // 按照自定义的方式来配置返回的HTTP响应
  }
}
// 在特定的路由或控制器使用
@UseFilters(new TransformFilter())
@Controller('example')
export class ExampleController {
}

异常记录

在捕获异常的同时,使用过滤器记录错误信息。

@Catch()
export class LoggingFilter implements ExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    // 记录异常堆栈信息
    console.error(exception);
  }
}
// 在全局或特定路由使用
app.useGlobalFilters(new LoggingFilter());

使用案例

全局异常过滤器

@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();
    const status = exception instanceof HttpException ? exception.getStatus() : 500;

    // 以统一的JSON格式返回错误信息
    response
      .status(status)
      .json({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}
// 在主文件中全局注册这个过滤器
app.useGlobalFilters(new AllExceptionsFilter());

记录异常过滤器

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    // 将异常信息输出到控制台
    console.error(`Exception occurred: ${exception.message}`);
  }
}
// 在指定的控制器或方法上通过使用装饰器使用这个过滤器
@UseFilters(HttpExceptionFilter)
export class ExampleController {
}

注意

在过滤器中应避免进行太复杂的操作,以免增加调试的难度和系统的复杂性。