You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS中AWS S3读取流未关闭引发超时错误的解决方法

问题解决:NestJS中ZIP生成请求超时(流未正确关闭)

你遇到的Error [TimeoutError]: Connection timed out after 120000ms,本质是处理S3文件流与archiver压缩流时,未正确关闭所有流资源,导致Promise一直处于pending状态,请求无法正常结束。以下是针对性的修复方案:

核心修复逻辑:确保所有流闭环并触发Promise resolve

1. 完整处理archiver与S3上传流的生命周期

使用archiver生成ZIP时,必须监听finish事件,主动调用archiver.finalize(),同时绑定S3上传流的close/error事件,确保所有流完成后再resolve Promise。

2. 主动销毁异常或已完成的S3下载流

从S3获取PDF的读流出现错误,或流使用完成后,需主动调用stream.destroy()释放资源,避免流占用导致Promise无法收尾。

修复后的关键代码示例

async function generateAndUploadZip(s3Client: S3, pdfKeys: string[], zipKey: string): Promise<string> {
  return new Promise((resolve, reject) => {
    const archive = archiver('zip', { zlib: { level: 6 } });
    const uploadParams = {
      Bucket: process.env.S3_BUCKET,
      Key: zipKey,
      Body: archive,
    };

    // 绑定S3上传流事件
    const uploadStream = s3Client.upload(uploadParams);
    uploadStream.on('error', (err) => {
      archive.destroy();
      reject(err);
    });

    // 绑定archiver事件
    archive.on('error', (err) => {
      uploadStream.abort();
      reject(err);
    });
    archive.on('finish', () => {
      uploadStream.send()
        .then(data => resolve(data.Location))
        .catch(reject);
    });

    // 批量添加PDF文件到ZIP
    for (const key of pdfKeys) {
      const getObjectParams = { Bucket: process.env.S3_BUCKET, Key: key };
      const pdfStream = s3Client.getObject(getObjectParams).createReadStream();
      
      pdfStream.on('error', (err) => {
        archive.destroy();
        uploadStream.abort();
        reject(err);
      });
      
      archive.append(pdfStream, { name: `${key.split('/').pop()}` });
    }

    // 启动压缩并关闭archiver
    archive.finalize();
  });
}

额外注意事项

  • 所有流的error事件必须监听,未捕获的流错误会直接导致Promise pending
  • NestJS控制器中需确保返回的Promise正确resolve/reject,框架会自动结束请求
  • ZIP文件已存在的分支逻辑需独立处理,避免不必要的流操作引发资源泄漏

内容的提问来源于stack exchange,提问作者Izlia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 00:45:06