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

无法捕获FilesInterceptor抛出的BadRequestException求助

NestJS Multer文件上传数量超限异常无法被HttpException识别的问题

在NestJS中使用FilesInterceptor实现多文件上传,控制器代码如下:

import { Controller, FileValidator, ParseFilePipe, Post, UploadedFiles, UseInterceptors } from '@nestjs/common';
import { FilesInterceptor } from '@nestjs/platform-express';
import { Public } from 'src/auth/decorators/public.decorator';
import { MimeTypeValidationPipe } from './pipes/mimetype.validation.pipe';

const ACCEPTED_FILE_MIMETYPES = ["image/jpeg", "image/jpg", "image/png"]
const validators: FileValidator[] = [
    new MimeTypeValidationPipe({ accepted: ACCEPTED_FILE_MIMETYPES })
];

@Controller('uploads')
export class UploadsController {

    @Public()
    @Post("/")
    @UseInterceptors(FilesInterceptor("files"))
    public async create(
        @UploadedFiles(new ParseFilePipe({ validators })) 
        files: Express.Multer.File[]
    ){
        files[0].originalname
        const filenames = files.map(({ originalname }) => originalname)
        return { filenames };
    }
}

测试上传文件数量超限场景时,服务器返回500错误,自定义异常过滤器无法识别该异常为HttpException子类,尽管Nest源码中transformException已将Multer的数量错误转为BadRequestException(HttpException子类)。自定义过滤器代码如下:

@Catch()
class TestFilter implements ExceptionFilter {
    catch(exception: any, host: ArgumentsHost) {
        console.debug(exception)
        if(exception instanceof HttpException) console.debug("This is an HTTP Exception !");
        else console.debug("This is NOT an HTTP Exception");
        const response = host.switchToHttp().getResponse<Response>();
        return response.status(500).json({statusCode: 500 , message: "ERROR" });
    }
}

问题原因

核心原因是依赖版本不一致导致的类实例判定失效:

  • 项目中存在多版本@nestjs/common包(直接依赖与间接依赖版本不同)
  • 抛出的BadRequestException来自某一版本包,而过滤器中导入的HttpException来自另一版本,导致instanceof判定失败

解决方法

1. 统一NestJS依赖版本

  • 删除项目根目录的node_modules文件夹和package-lock.json/yarn.lock文件
  • 执行npm install或yarn install重新安装依赖,确保所有@nestjs/*系列包版本完全一致

2. 修改异常判定逻辑

若暂时无法统一版本,可通过检查异常属性替代instanceof判定:

@Catch()
class TestFilter implements ExceptionFilter {
    catch(exception: any, host: ArgumentsHost) {
        console.debug(exception);
        // 通过异常名称或getStatus方法判定是否为HttpException子类
        const isHttpException = exception.name === 'BadRequestException' || typeof exception.getStatus === 'function';
        console.debug(isHttpException ? "This is an HTTP Exception !" : "This is NOT an HTTP Exception");
        
        const response = host.switchToHttp().getResponse<Response>();
        // 优先使用异常自带的状态码
        const statusCode = typeof exception.getStatus === 'function' ? exception.getStatus() : 500;
        return response.status(statusCode).json({
            statusCode,
            message: exception.message || "ERROR"
        });
    }
}

3. 显式配置文件数量上限

在FilesInterceptor中明确设置允许的最大文件数,确保Multer触发的异常能被Nest正确转换:

// 示例:限制最多上传3个文件
@UseInterceptors(FilesInterceptor("files", 3))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 22:35:20