我正在尝试设置一个逻辑来使用Multer保存上传的文件。为此,我遵循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(就好像错误没有得到处理一样)。然后,我尝试使用如下所示的ExcepetionFilter来捕获它:
@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" });
}
}
我得到了以下输出:
BadRequestException: Too many files
at transformException (~/development/Nest/nestapi/node_modules/@nestjs/platform-express/multer/multer/multer.utils.js:19:20)
at ~/development/Nest/nestapi/node_modules/@nestjs/platform-express/multer/interceptors/files.interceptor.js:18:73
at ~/development/Nest/nestapi/node_modules/@nestjs/platform-express/node_modules/multer/lib/make-middleware.js:53:37
at AsyncResource.runInAsyncScope (node:async_hooks:202:9)
at listener (~/development/Nest/nestapi/node_modules/@nestjs/platform-express/node_modules/on-finished/index.js:170:15)
at onFinish (~/development/Nest/nestapi/node_modules/@nestjs/platform-express/node_modules/on-finished/index.js:101:5)
at callback (~/development/Nest/nestapi/node_modules/@nestjs/platform-express/node_modules/ee-first/index.js:55:10)
at IncomingMessage.onevent (~/development/Nest/nestapi/node_modules/@nestjs/platform-express/node_modules/ee-first/index.js:93:5)
at IncomingMessage.emit (node:events:539:35)
at endReadableNT (node:internal/streams/readable:1345:12) {
response: { statusCode: 400, message: 'Too many files', error: 'Bad Request' },
status: 400
}
This is NOT an HTTP Exception
筛选器指示它不是HTTPException。然而,在深入研究FilesInterceptor.ts代码时,我注意到捕获的错误是由一个小的实用函数“TransException”处理的,该函数应该将Multer错误转换为HttpException(取决于Multer返回的错误代码)
muter.utils.ts文件(来自Nest repo)
import {
BadRequestException,
HttpException,
PayloadTooLargeException,
} from '@nestjs/common';
import { multerExceptions } from './multer.constants';
export function transformException(error: Error | undefined) {
if (!error || error instanceof HttpException) {
return error;
}
switch (error.message) {
case multerExceptions.LIMIT_FILE_SIZE:
return new PayloadTooLargeException(error.message);
case multerExceptions.LIMIT_FILE_COUNT:
case multerExceptions.LIMIT_FIELD_KEY:
case multerExceptions.LIMIT_FIELD_VALUE:
case multerExceptions.LIMIT_FIELD_COUNT:
case multerExceptions.LIMIT_UNEXPECTED_FILE:
case multerExceptions.LIMIT_PART_COUNT:
return new BadRequestException(error.message);
}
return error;
}
我不明白为什么我的过滤器(和NestJS的unhandledExceptionFilter)不能检测到这个异常,因为对我来说,它应该是HttpException的一个示例。
你能帮帮我吗?
诚挚的问候
2条答案
按热度按时间9o685dep1#
您的项目中可能包含两个@nestjs/Common副本。创建错误的代码正在使用一个副本,而您的异常筛选器正在使用另一个副本。当您的代码检查
instanceof
时,它检查异常是否是来自@nestjs/Common的It‘s副本的HttpException
的示例,但不是,它是来自@nestjs/Common的另一个副本的HttpException
的示例。这称为“多领域”(请参阅https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof#instanceof_and_multiple_realms).解决这个问题的方法是确保您的项目中只有一个@nestjs/Common副本。通常,您有2个是因为您有2个不同版本规格的Package.json文件(例如,一个Package.json中的“@nestjs/Common”:“^8.0.0”,而另一个中的“@nestjs/Common”:“^9.0.0”)。您可能需要使用
overrides
键来强制依赖项使用与您在其他地方使用的版本相同的版本。希望这能帮上忙!
9wbgstp72#
抱歉的!
我想问题出在我身上。
Multer的LTS版本(1.4.4-lts.1)有缺陷。因此,我决定降级到1.4.4(没有出现问题的错误的版本)。但要做到这一点,我必须通过在
node_modules/@nest/platform-express
目录中执行npm install multer@1.4.4
来手动降级嵌套依赖项。但就在那时,Nestjs开始对我的错误进行糟糕的格式化。
有趣的是,返回(
npm install multer@1.4.4-lts.1
到node_modules/@nest/platform-express
目录)并不能解决问题(错误处理仍然很糟糕),我不得不删除node_modules/@nest/platform-express
文件夹并从项目的根目录重新安装包,以使一切恢复正常(当然,还有LTS版本的错误)。好奇怪啊。