我正在使用此中间件将文件上传到 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 会跳过该文件而不触发错误,但如果它不是有效的文件类型,我想抛出一个错误,并且我需要将该无效文件类型错误发送给客户端
我相信 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'))
}
}