使用 multer(upload.any() ) 时无法向客户端发送适当的错误消息

问题描述 投票:0回答:1

我正在使用此中间件将文件上传到 AWS S3 存储桶。但是,出现了一个问题:在 fileFilter 中过滤文件类型时,无法进入 Multer 的错误块。


const multer = require('multer');
const storage = multer.memoryStorage();
const crypto = require('crypto');
const sharp = require('sharp');
const { AwsUploadFile } = require('../../utils/s3');

const generateFileName = (mimeType, bytes = 32) => {
  const extension = mimeType.split('/')[1]; // Extracts file extension from MIME type
  return crypto.randomBytes(bytes).toString('hex') + '.' + extension;
};

const fileFilter = (req, file, cb) => {
  if (
    file.mimetype.startsWith('image/') ||
    file.mimetype.startsWith('video/')
  ) {
    cb(null, true);
  } else {
    cb(null, false);
  }
};

const upload = multer({
  storage: storage,
  limits: { fileSize: 50 * 1024 * 1024 }, // 50MB limit
  fileFilter: fileFilter,
});

async function fileUpload(req, res, next) {
  const multerUpload = upload.any();
  multerUpload(req, res, async (err) => {
    if (err instanceof multer.MulterError) {
      return res.status(500).json({
        success: false,
        message: 'Error uploading file',
        error: err.message,
      });
    } else if (err) {
      // An unknown error occurred when uploading.
      console.log('General error:', err.message);

      return res.status(500).json({
        success: false,
        message: 'An error occurred while processing',
        error: err.message,
      });
    }

    if (!req.files || req.files.length === 0) {
      return res.status(400).json({
        success: false,
        message: 'No files uploaded',
      });
    }

    const file = req.files[0];
    const getFileName = generateFileName(file.mimetype);
    file.originalname = file.mimetype.startsWith('video/')
      ? 'public/videos/' + getFileName
      : 'public/images/' + getFileName;

    if (file.mimetype.startsWith('image/')) {
      try {
        const fileBuffer = await sharp(file.buffer)
          .resize({ height: 1920, width: 1080, fit: 'contain' })
          .toBuffer();

        file.buffer = fileBuffer;
      } catch (sharpError) {
        return res.status(500).json({
          success: false,
          message: 'Error processing image',
          error: sharpError.message,
        });
      }
    }

    try {
      const { fileLink, result } = await AwsUploadFile({
        fileBuffer: file.buffer,
        fileName: file.originalname,
        mimeType: file.mimetype,
      });

      req.fileUrl = fileLink;
      req.fileType = file.mimetype.split('/')[0];
      next();
    } catch (awsError) {
      return res.status(500).json({
        success: false,
        message: 'Error uploading to AWS',
        error: awsError.message,
      });
    }
  });
}

module.exports = fileUpload;

如果我抛出错误,那么我可以进入它,但我无法发送这些标头:

return res.status(500).json({ success: false, message: 'An error occurred while processing', error: err.message })
当我在 fileFilter 函数中使用 cb(null, false) 时,Multer 会跳过该文件而不触发错误,但如果它不是有效的文件类型,我想抛出一个错误,并且我需要将该无效文件类型错误发送给客户端

javascript node.js amazon-s3 async-await multer
1个回答
0
投票

我相信 Multer 中的 fileFilter 函数旨在根据某些条件简单地过滤掉文件,并且它不会直接将错误传播到错误处理程序。如果您想将无效文件类型作为错误处理并向客户端返回响应,可以尝试在遇到无效文件类型时在 fileFilter 函数中抛出错误。 Multer 应该捕获此错误,并且您可以在中间件的错误块中处理它。尝试这样的事情,

const fileFilter = (req, file, cb) => {
  if (file.mimetype.startsWith('image/') || file.mimetype.startsWith('video/')) {
    cb(null, true)
  } else {
    cb(new Error('Invalid file type'))
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.