访问IBM Cloud对象存储不存在文件 已捕获错误仍致Node.js服务崩溃
问题根因
- 所有你写在异步回调(SDK请求回调、流事件回调)里的
throw err都不属于外层getCV的Promise调用链,外层的.catch()无法捕获这类异步抛出的错误,最终成为Node.js进程的未捕获异常,直接触发服务崩溃。 - 你在流的error处理逻辑里注释了正确的响应返回代码,反而保留了
throw err,进一步放大了问题。
修复步骤
1. 调整getFileStream逻辑
保留错误日志即可,不要在SDK请求的error回调里抛出错误,错误会自动冒泡到后续创建的可读流的error事件中:
export const getFileStream = (itemName) => { return cos.getObject({ Bucket: bucketName, Key: itemName }).on('error',(err)=>{ console.log("we've got an error:", err.message); // 移除原有的throw err逻辑 }).createReadStream(); };
2. 调整业务调用逻辑
去掉流回调里的抛出逻辑,直接返回404响应,同时把混用的await + then改成纯async/await写法,避免Promise链混乱,增加响应头已发送判断避免重复返回报错:
export const getCV = async (req, res) => { if (!req.params.id) return res.status(404).json({ message: "Invalid profile id!" }); try { const details = await UserModel.findById(req.params.id, '-password'); if (!details) return res.status(404).json({ message: 'User not found!' }); if (!details.CV) return res.status(404).json({ message: 'No CV found!' }); res.attachment('CV.pdf'); res.set("Content-Type", "application/pdf"); getFileStream(details.CV) .on('error', (err) => { if (!res.headersSent) { return res.status(404).json({ message: err.message }); } }) .pipe(res); } catch(err) { if (!res.headersSent) { return res.status(404).json({ message: err.message }); } } };
兜底补充
如果要进一步避免极端场景下的服务崩溃,可以在进程启动逻辑中增加全局事件监听,做异常日志上报和优雅处理:
// 进程启动入口添加 process.on('uncaughtException', (err) => { console.error('未捕获异常:', err); // 可在这里添加日志上报逻辑 }); process.on('unhandledRejection', (reason) => { console.error('未处理的Promise拒绝:', reason); });
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

