multerfilesizeupload-max-filesize

Issue with file size validation using multer middleware in Node.js


I'm having an issue with validating the file size using the multer middleware in a Node.js application. I have implemented a custom middleware setFileLimit to set the file size limit based on the file type, but it seems that the req.file and req.files are undefined when the middleware is executed.

not able to validate the file size before uploading the selected media to multer.

If I remove the setFileLimit function I am able to access the file in multer and I will get the link of the media, then I can use it to storein DB.

Frontend Code:

// 1. Frontend code that sends the media
if (file) {
  const formData = new FormData()
  formData.append('medias', file)
  console.log('send rrrr--');
  console.log('type of formdata--', typeof formData);
  const mediatoCloudinary = await uploadMedia(formData)
  if (mediatoCloudinary?.status === 400) {
    console.log('media upload error', mediatoCloudinary);
    setMediaError('No media file found.')
  }
}

export const uploadMedia = async(formData) => {
  try {
    console.log('rrr--', formData);
    const result = await axiosApi.post(messagesRoute.sendMedia, formData)
    console.log('media link', result);
    return result.data
  } catch (error) {
    console.log('media error', error.message);
    return error.response
  }
}

//2.Backend Route:

router.post('/sendMedia', setFileLimit, multerMid.single('medias'), catchAsyncErrors((req: Req, res: Res, next: Next) => {
  console.log('in send media route');
  messageController.saveMediaToCloudinary(req, res, next)
}))


//3.Multer Middleware and setFileLimit function in backend:

// Custom middleware to set limits based on file type using startsWith
const setFileLimit = (req: Req, res: Res, next: Next) => {
  // Access the file using the correct key ('medias')
  console.log('Accessing file:', req.file, 'req.files--', req.files);
  const file = req.file
  if (!file) {
    return res.status(400).send('No media file found.');
  }

  let maxSize;
  if (file.mimetype.startsWith('image/')) {
    maxSize = 5 * 1024 * 1024; // 5 MB for images
  } else if (file.mimetype.startsWith('video/')) {
    maxSize = 10 * 1024 * 1024; // 10 MB for videos
  } else {
    maxSize = 5 * 1024 * 1024; // Default to 5 MB for other documents
  }

  if (file.size > maxSize) {
    return res.status(400).json({ error: 'File size exceeds the limit.' });
  }

  next()
}

const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    const uploadDirectory = path.join(__dirname, '../public/media')
    if (!fs.existsSync(uploadDirectory)) {
      fs.mkdirSync(uploadDirectory, { recursive: true });
    }
    cb(null, uploadDirectory);
  },
  filename: (req, file, cb) => {
    console.log('file in multer--', file);
    const uniqueSuffix = uuidv4() + '-' + file.originalname
    cb(null, uniqueSuffix);
  },
});

const multerMid = multer({
  storage: storage,
  limits: {
    fieldNameSize: 100,
    fieldSize: 5 * 1024 * 1024
  }
});

export { multerMid, setFileLimit }

Solution

  • Try rearranging the middleware so that multerMid.single('medias') is executed before setFileLimit

    router.post('/sendMedia', multerMid.single('medias'), setFileLimit,catchAsyncErrors((req: Req, res: Res, next: Next) => {  console.log('in send media route');  messageController.saveMediaToCloudinary(req, res, next)}))