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

在NestJS中使用class-validator自定义结构化验证错误响应

实现自定义参数校验错误响应格式

在NestJS中,要将class-validator返回的字符串数组错误信息转为包含字段名的对象数组,需要通过自定义异常过滤器重写默认的错误处理逻辑,具体步骤如下:

1. 创建自定义异常过滤器

新建过滤器文件(如src/common/filters/validation-exception.filter.ts),捕获BadRequestException并处理校验错误:

import { ExceptionFilter, Catch, ArgumentsHost, BadRequestException } from '@nestjs/common';
import { Response } from 'express';
import { ValidationError } from 'class-validator';

@Catch(BadRequestException)
export class ValidationExceptionFilter implements ExceptionFilter {
  catch(exception: BadRequestException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const exceptionResponse = exception.getResponse() as { message: ValidationError[] | string[] };

    // 转换校验错误为目标格式
    const formattedErrors = Array.isArray(exceptionResponse.message)
      ? exceptionResponse.message.flatMap((error) => {
          if (typeof error === 'string') {
            return [{ field: 'unknown', error }];
          }
          // 遍历字段的所有校验错误
          return Object.values(error.constraints).map((msg) => ({
            field: error.property,
            error: msg,
          }));
        })
      : [{ field: 'unknown', error: exceptionResponse.message }];

    response.status(exception.getStatus()).json({
      message: formattedErrors,
      // 若需保留statusCode、error字段可取消注释
      // statusCode: exception.getStatus(),
      // error: exception.name,
    });
  }
}

2. 注册全局过滤器

在main.ts中注册过滤器,让全局校验错误统一使用该处理逻辑:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationExceptionFilter } from './common/filters/validation-exception.filter';

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

关键说明

  • 过滤器自动捕获ValidationPipe抛出的BadRequestException,从异常响应中提取原始ValidationError数组
  • 通过ValidationError的property(字段名)和constraints(错误信息),将每个校验错误转换为{ field: string, error: string }格式的对象
  • 若只需在特定控制器/方法生效,可在对应位置使用@UseFilters(ValidationExceptionFilter)装饰器替代全局注册

配置完成后,校验错误响应会符合预期格式:

{
  "message": [
    { "field": "title", "error": "Title is too long. Maximal length is 50 characters, but actual is testtesttesttesttesttesttesttesttesttesttesttesttesttesttest" },
    { "field": "title", "error": "Title is too short. Minimal length is 10 characters, but actual is abc" }
  ]
}

内容的提问来源于stack exchange,提问作者Shivansh Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 08:35:05