AWS Lambda Node.js环境调用S3.putObject无法执行问题求助
问题根因
- 异步逻辑未等待执行:你声明了
async类型的Lambda handler,但调用回调风格的s3.putObject时没有等待异步任务结束,handler的同步代码执行完成后Lambda就直接终止运行,导致putObject的回调逻辑从未被触发,因此既没有回调日志打印,也没有文件上传到S3。 - 变量作用域错误:
putObjectToS3函数内部使用的context是handler的入参,你没有将context传入该函数,就算回调能执行也会抛出context is not defined的错误。 - 时间解析异常:运行日志显示日期为
1970/01/01,说明你拿到的event.Records[0].Sns.Timestamp值无法被Date对象正确解析,需要检查该字段的实际格式是否符合预期。
修复方案
推荐将回调式调用改为Promise + await的方式适配async handler,修复后的完整代码如下:
var aws = require('aws-sdk'); var s3 = new aws.S3({ apiVersion: '2006-03-01' }); var bucket = 'ashish-3245'; var acl = 'public-read'; var s3prefix = 'DeepSecurityEvents/'; var ext = '.json'; exports.handler = async(event, context) => { try { //console.log('Received event:', JSON.stringify(event, null, 2)); const message = event.Records[0].Sns.Message; console.log("records", message); var timestamp = event.Records[0].Sns.Timestamp; // 新增时间有效性校验 const dateObj = new Date(timestamp); if (isNaN(dateObj.getTime())) { throw new Error(`无效的时间戳:${timestamp}`); } var date = getFormattedDate(dateObj); console.log('from date', date); // 追加5位随机数,避免同一毫秒收到两条消息时覆盖已有文件 var random5digits = Math.floor(Math.random() * 90000) + 10000; // 示例路径:DeepSecurityEvents/2016/07/20/2016-07-20T15:30:00.000Z12345.json var filename = s3prefix + date + '/' + timestamp + random5digits + ext; // 等待S3上传完成 const uploadRes = await putObjectToS3(message, filename); console.log('S3上传成功:', uploadRes); console.log('From S3:', message); console.log(filename); return {statusCode: 200, body: '上传成功'}; } catch (err) { console.error('执行出错:', err); throw err; } }; function getFormattedDate(d) { // 返回格式为yyyy/MM/dd的日期 return d.getFullYear() + '/' + twoDigits(d.getMonth() + 1) + '/' + twoDigits(d.getDate()); } function twoDigits(n) { return n < 10 ? '0' + n : n; } // 改为返回Promise适配await function putObjectToS3(message, filename) { console.log('准备上传到S3:', message); var params = { Bucket: bucket, Key: filename, ACL: acl, Body: message }; return s3.putObject(params).promise(); }
额外注意事项
- 请确认Lambda执行角色已经附加了
s3:PutObject权限,且权限的资源范围包含你使用的S3存储桶路径 - 如果S3存储桶开启了加密,需要在putObject的params中补充对应的加密配置
- 请确认你使用的S3存储桶名称、区域配置正确,没有跨区域访问的问题
内容的提问来源于stack exchange,提问作者Hacker
相关产品推荐
相关产品推荐

