Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to prevent file upload when body validation fails in nestjs

I have the multipart form to be validated before file upload in nestjs application. the thing is that I don't want the file to be uploaded if validation of body fails. here is how I wrote the code for.

// User controller method for create user with upload image
@Post()
@UseInterceptors(FileInterceptor('image'))
create(
    @Body() userInput: CreateUserDto,
    @UploadedFile(
        new ParseFilePipe({
          validators: [
             // some validator here
          ]
        })
    ) image: Express.Multer.File,
) {
    return this.userService.create({ ...userInput, image: image.path });
}

Tried so many ways to turn around this issue, but didn't reach to any solution

like image 550
Mohsen Amani Avatar asked Sep 12 '25 15:09

Mohsen Amani


2 Answers

Interceptors run before pipes do, so there's no way to make the saving of the file not happen unless you manage that yourself in your service. However, another option could be a custom exception filter that unlinks the file on error so that you don't have to worry about it post-upload

like image 51
Jay McDoniel Avatar answered Sep 14 '25 05:09

Jay McDoniel


This is how I created the whole filter

import { isArray } from 'lodash';
import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  BadRequestException,
} from '@nestjs/common';
import { Request, Response } from 'express';
import * as fs from 'fs';

@Catch(BadRequestException)
export class DeleteFileOnErrorFilter implements ExceptionFilter {
  catch(exception: BadRequestException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();
    const status = exception.getStatus();

    const getFiles = (files: Express.Multer.File[] | unknown | undefined) => {
      if (!files) return [];
      if (isArray(files)) return files;
      return Object.values(files);
    };

    const filePaths = getFiles(request.files);

    for (const file of filePaths) {
      fs.unlink(file.path, (err) => {
        if (err) {
          console.error(err);
          return err;
        }
      });
    }
    response.status(status).json(exception.getResponse());
  }
}
like image 44
ElZombieIsra Avatar answered Sep 14 '25 06:09

ElZombieIsra