Node.js中如何捕获fs.createReadStream错误?zip解压无报错卡住求解
排查思路
- 补全所有流的错误监听
你现在只监听了pipe返回的目标流的error事件,源文件读取流fs.createReadStream、解压转换流unzip.Extract的错误都没有做监听,大部分解压异常会从unzipPipe对象抛出,未被监听的错误会导致进程直接崩溃或者无响应。
修正后的代码示例:
const unzip = require("unzip-stream"); const fs = require("fs"); function extractFileAndParse(file, timeout = 30000) { return new Promise(function (resolve, reject) { // 加超时兜底避免永久卡住 const timer = setTimeout(() => { // 超时后销毁所有流避免内存泄漏 readStream.destroy(); unzipPipe.destroy(); reject(new Error('解压超时')); }, timeout); let extractedDirName = file.replace(".zip", ""); let unzipPipe = unzip.Extract({ path: `./directory/${extractedDirName}`, }); // 监听解压流的错误 unzipPipe.on('error', (err) => { clearTimeout(timer); console.log('解压出错:', err); reject(err); }); try { let readStream = fs.createReadStream(`${directory}/${file}`); // 监听源文件读取流的错误 readStream.on('error', (err) => { clearTimeout(timer); console.log('读取文件出错:', err); reject(err); }); let stream = readStream.pipe(unzipPipe); stream.on("finish", function () { clearTimeout(timer); return resolve({ contentid: extractedDirName, }); }); stream.on("error", (err) => { clearTimeout(timer); return reject(err); }); } catch (error) { clearTimeout(timer); console.log("处理文件时发生错误: ", error); reject(error); } }); }
- 验证异常压缩包的有效性
先用系统自带的解压工具打开触发问题的压缩包,确认是否存在损坏、加密、固实压缩、非标准压缩算法等问题,unzip-stream多年未维护,对很多边界场景的兼容能力很差,遇到非标准zip很容易卡住不抛错。 - 检查写入环境异常
确认解压目标目录./directory/${extractedDirName}的读写权限是否正常,对应磁盘分区是否有足够的存储空间存储解压后的文件,写入权限不足、磁盘已满都会导致写入流卡住无响应。 - 更换更稳定的解压依赖
如果上述排查都没有解决问题,可以替换unzip-stream为维护更活跃、异常处理更完善的解压库,比如yauzl或者adm-zip,这两个库对异常压缩包的容错能力更强,不会出现无响应的情况。
内容的提问来源于stack exchange,提问作者justAnAnotherCoder
相关产品推荐
相关产品推荐

