Express框架下如何处理AWS S3存储桶文件不存在的报错问题
问题原因
你现在用的同步try/catch只能捕获创建流过程中触发的同步异常,而S3对象不存在、权限不足这类错误是流已经创建完成后异步抛出的,自然不会被外层的同步try/catch捕获,最终导致进程未处理异常崩溃。
修复方案
给返回的可读流添加error事件监听,主动捕获异步流错误即可,修改后的控制器代码如下:
public getImage(request: Request, response: Response): void { try { const key = request.params.key; const read = getFileStream(key); // 新增流错误监听,捕获异步异常 read.on('error', (err) => { // 销毁流避免内存泄漏 read.destroy(); // 按错误类型返回对应响应 if ((err as any)?.statusCode === 404 || err.name === 'NoSuchKey') { return response.status(404).json({ message: 'Image not found.' }); } // 其他错误统一返回对应状态码,比如权限不足返回403 return response.status((err as any)?.statusCode ?? 500).json({ message: err.message ?? 'Failed to load resource' }); }); return read.pipe(response); } catch (error) { // 保留原有捕获逻辑,处理创建流阶段的同步错误 return response.status(404).json({ message: 'Image not found.' }); } }
补充说明
你遇到的「Access denied」报错本质是S3的默认安全策略:如果你的访问凭证没有对应Bucket的s3:ListBucket权限,S3会对所有不存在的Key统一返回403状态码而不是404,避免攻击者枚举Bucket内的对象。如果需要区分「对象不存在」和「真·权限不足」,可以给对应凭证添加s3:ListBucket权限,此时不存在的Key会返回404错误,更符合业务预期。
内容的提问来源于stack exchange,提问作者JuanDa237
相关产品推荐
相关产品推荐

