使用Multer(upload.any())无法向客户端返回非法文件类型错误
解决Multer fileFilter无法触发错误处理的问题
要实现文件类型不合法时触发错误并返回指定响应,你需要调整fileFilter的回调方式,并在错误处理逻辑中区分自定义错误类型:
修改步骤:
调整fileFilter的错误触发方式:
不再使用cb(null, false)跳过文件,而是通过cb(new Error())主动抛出错误,错误信息明确说明文件类型问题。优化错误处理逻辑:
在multer的回调错误处理中,判断错误信息,返回400状态码(客户端错误)而非500(服务器错误),同时返回自定义的错误提示。
修改后的完整代码:
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(new Error('仅支持图片和视频类型的文件')); } }; 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: err.message, }); } else if (err) { // 判断是否为文件类型错误,返回400客户端错误 if (err.message === '仅支持图片和视频类型的文件') { return res.status(400).json({ success: false, message: '文件类型不合法', error: err.message, }); } // 其他未知错误 console.log('通用错误:', err.message); return res.status(500).json({ success: false, message: '处理过程中发生错误', error: err.message, }); } if (!req.files || req.files.length === 0) { return res.status(400).json({ success: false, message: '未上传任何文件', }); } 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: 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: '上传至AWS失败', error: awsError.message, }); } }); } module.exports = fileUpload;
关键说明:
fileFilter中使用cb(new Error('xxx'))会直接触发multer回调的错误分支,替代原来的跳过逻辑。- 在错误处理中通过判断错误信息,将文件类型错误归类为客户端错误(400状态码),更符合HTTP语义,同时返回清晰的提示信息给客户端。
- 保留了对Multer内置错误(如文件大小超限)和其他未知错误的区分处理,保证逻辑完整性。
内容的提问来源于stack exchange,提问作者Jagadeesh
相关产品推荐
相关产品推荐

