You need to enable JavaScript to run this app. 请求AWS S3不存在的对象触发Access Denied导致Node服务器崩溃如何解决
优惠活动
大模型
产品
解决方案
定价
更多

请求AWS S3不存在的对象触发Access Denied导致Node服务器崩溃如何解决

问题原因

  • try/catch 仅能捕获同步执行阶段抛出的异常:调用s3.getObject(downloadParams).createReadStream()的同步执行阶段只要参数合法就不会抛出错误,实际的S3资源请求是流后续异步发起的,出现的Access Denied错误是通过流的error事件抛出的,没有被监听的话会成为未捕获异常,直接导致Node进程崩溃。
  • S3权限特性:如果你的访问身份没有配置s3:ListBucket权限,请求不存在的对象时S3不会返回404状态,而是直接返回403 Access Denied,这是你看到该报错的业务侧原因,但该问题本身不会直接导致服务崩溃。

修复方案

首先给返回的可读流添加error事件监听,捕获异步抛出的S3请求错误即可解决崩溃问题,代码修改如下:

const getFileStream = fileName => {
  const downloadParams = {
    Key: fileName,
    Bucket: bucketName
  }
  return s3.getObject(downloadParams).createReadStream()
}

app.get('/aws-images/:id', jsonParser, (req, res) => {
  const id = req.params.id
  try {
    const readStream = getFileStream(id)
    // 监听流的错误事件,捕获异步抛出的S3请求错误
    readStream.on('error', err => {
      // 可根据错误码自定义返回内容
      if (err.statusCode === 403 || err.statusCode === 404) {
        res.status(404).json({msg: '请求的资源不存在'})
      } else {
        res.status(500).json(err)
      }
    })
    readStream.pipe(res)
  } catch (err) {
    // 保留原有捕获逻辑,处理同步阶段的参数错误等场景
    res.status(500).json(err)
  }
})

如果需要让不存在的对象返回标准404而不是403,可以给你的S3访问身份添加s3:ListBucket权限,配置示例如下(替换为实际桶名):

{
  "Effect": "Allow",
  "Action": "s3:ListBucket",
  "Resource": "arn:aws:s3:::你的桶名"
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 14:24:03