You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS自定义ExceptionFilter无法捕获错误JSON请求的问题及解决方案咨询

你说得完全对——这种JSON格式错误的异常确实是NestJS在请求到达控制器之前就处理了,而且它属于原生SyntaxError,不是你过滤器里指定捕获的HttpException,所以你的HttpExceptionFilter根本没机会触发。下面是具体的解决步骤:

1. 修改过滤器,捕获SyntaxError

首先,更新你的HttpExceptionFilter,让它同时处理HttpException和SyntaxError。在@Catch装饰器里添加SyntaxError,并在catch方法中区分异常类型:

import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
import { Request, Response } from 'express';

@Catch(HttpException, SyntaxError)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException | SyntaxError, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();

    // 处理JSON解析错误的场景
    if (exception instanceof SyntaxError) {
      return response.status(400).json({
        statusCode: 400,
        message: '请求体格式无效,请提供合法的JSON数据',
        error: 'Invalid JSON Payload',
        timestamp: new Date().toISOString(),
        path: request.url
      });
    }

    // 处理原有HttpException的逻辑
    const status = exception.getStatus();
    response.status(status).json({
      statusCode: status,
      message: exception.message,
      timestamp: new Date().toISOString(),
      path: request.url
      // 你原来的自定义字段都可以保留
    });
  }
}

2. 全局绑定过滤器(关键!)

之前你只在AppController上绑定了过滤器,但JSON解析错误发生在路由处理之前,控制器级别的过滤器无法捕获这个阶段的异常。你需要把过滤器设置为全局生效:

方法一:通过main.ts全局注册

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { HttpExceptionFilter } from './http-exception.filter';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  // 全局绑定过滤器
  app.useGlobalFilters(new HttpExceptionFilter());
  await app.listen(3000);
}
bootstrap();

方法二:通过模块提供者注册(支持依赖注入)

如果你需要在过滤器中注入其他服务,更推荐这种方式。在AppModule中添加APP_FILTER提供者:

import { Module } from '@nestjs/common';
import { APP_FILTER } from '@nestjs/core';
import { HttpExceptionFilter } from './http-exception.filter';
import { AppController } from './app.controller';

@Module({
  controllers: [AppController],
  providers: [
    {
      provide: APP_FILTER,
      useClass: HttpExceptionFilter,
    },
  ],
})
export class AppModule {}

为什么之前的过滤器不生效?

简单来说:

  • JSON解析是Express/Koa底层完成的,当解析失败时会抛出SyntaxError,这个异常发生在NestJS的控制器处理流程之前
  • 你之前绑定的控制器级别过滤器,只能捕获控制器内部或其路由处理链中抛出的异常,碰不到这个早期阶段的错误
  • 全局过滤器会捕获整个应用中所有未被处理的异常,包括这种底层解析错误

现在再测试错误格式的JSON请求,应该就能得到你自定义的响应了。

内容的提问来源于stack exchange,提问作者Alexey Vasyanovich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 18:32:40