生产环境Multer S3出现畸形multipart未捕获异常,本地无法复现
复现方案
- 准备一个体积≥100MB的测试文件,避免上传速度过快还没终止就完成传输
- 使用curl命令发起上传请求:
curl -X POST -F "file=@/本地大文件路径" http://你的本地服务接口地址,请求发起后立刻按Ctrl+C终止curl进程,模拟上传中途断开的场景,大概率可以触发该错误 - 如果上述方式复现概率低,可以写自定义Node测试脚本,主动在上传中途销毁TCP连接,可100%触发该异常
修复方案
你当前代码无法捕获异常的原因是:该错误是在请求流层面由底层dicer库抛出,还未进入multer的upload回调逻辑,所以回调内的错误判断和try/catch都无法捕获。
1. 临时快速修复(无需改依赖版本)
在控制器层调用upload方法前,给req对象添加error事件监听,捕获流层面的错误:
// 新增请求流错误监听 req.on('error', err => { console.error('上传流异常:', err) if (!res.headersSent) { res.status(400).send(util.sendFormattedErrorResponse(MULTER_ERROR_CODES['INVALID_UPLOAD'])) } }) // 原有代码 let upload = util.uploadToS3(fileFilter, limits, process.env.Bucket, path).single('file'); upload(req, res, function(err) { // 保持你原有逻辑不变 console.log("inside upload"); try { if (err instanceof multer.MulterError || (err && MULTER_ERROR_CODES[err.code || err.message])) { return res .status(400) .send(util.sendFormattedErrorResponse(MULTER_ERROR_CODES[err.code || err.message])); } else if (err) { console.log(err); return res.status(500).send(util.sendFormattedErrorResponse(MULTER_ERROR_CODES['UNKNOWN'])); } } catch (e) { console.log(e); } })
同时在服务入口文件添加全局异常兜底监听,避免偶发漏网的异常导致服务崩溃:
// 全局未捕获同步异常兜底 process.on('uncaughtException', err => { console.error('全局未捕获异常:', err) // 可新增告警逻辑,非核心异常无需退出进程 }) // 全局未处理Promise rejection兜底 process.on('unhandledRejection', reason => { console.error('全局未处理Promise异常:', reason) })
2. 永久修复(推荐)
你使用的multer@1.4.2版本本身存在该错误未捕获的已知问题,直接升级multer到长期支持版本即可解决:
npm install multer@1.4.5-lts.1
升级后multer会自动捕获dicer抛出的异常,传递到upload的回调参数err中,你原有回调内的错误处理逻辑即可正常生效,不需要额外添加req的error监听。
内容的提问来源于stack exchange,提问作者sidd
相关产品推荐
相关产品推荐

