I am trying to set up a logic to save uploaded files using Multer. To do this, I follow the Nestjs tutorial and use the "FilesInterceptor" interceptor.
controller file :
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 };
}
}
However, when I test the behavior of the server when the number of uploaded files exceeds the limit, the server returns me an error 500 (As if the error was not handled). I then try to catch it by using an ExcepetionFilter like this one:
@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" });
}
}
And i get the following output :
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
The filter indicates that it is NOT an HTTPException. However, while digging in the FilesInterceptor.ts code I notice that the caught errors are handled by a small utility function "transformException" which is supposed to transform the Multer error into an HttpException (depending on the error code returned by Multer)
multer.utils.ts file (from 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;
}
I don't understand why my filter (and NestJS' unhandledExceptionFilter) can't detect this exception, since for me it is supposed to be an instance of HttpException.
Can you help me?
Best regards