S3.putObject - 回调永远不会被调用
Posted
技术标签:
【中文标题】S3.putObject - 回调永远不会被调用【英文标题】:S3.putObject - callback never gets called 【发布时间】:2015-07-28 14:12:55 【问题描述】:我正在尝试将图像上传到 S3,但是当我调用 s3.putObject(params, callback) 时,我的回调永远不会被调用,也不会记录任何错误。
以下是相关代码:
var params =
Key: key,
Body: imageData,
ContentLength: imageData.byteCount,
ContentType: contentType,
;
this.s3.putObject(params, function(err, data)
console.log('here');
if (err)
callback(err);
return;
callback(null, key);
);
params 是
Key: 'e2f99bf3a321282cc7dfaef69fe8ca62.jpg',
Body: imageData parsed from request using node-multiparty,
ContentLength: 27802,
ContentType: 'image/jpeg',
我已经验证 this.s3 是有效的,并且 typeof this.s3.putObject 的功能符合预期。
【问题讨论】:
您可能会通过安装并要求 npm 中的nock
模块获得一些见解,该模块将准确打印出请求的 URL。如果程序挂起等待回调,则可能是防火墙忽略了 TCP 连接尝试。您是否让程序挂起几分钟以查看它是否最终超时并调用回调?
您的程序是否在异步事件可以返回值之前完成执行?请参阅 AWS Lambda 的类似主题:***.com/questions/28449363/…
【参考方案1】:
如果此代码用于 lambda 函数,您需要在 putObject 的回调函数中添加 context.done(),如下所示:
s3.putObject(params, function(err, data)
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
context.done();
);
这会强制执行等到回调被填充后再退出。 为此,您还需要从主处理程序中删除任何 context.succeed 或 context.done(如果您有的话)。
【讨论】:
在这个......嗯......上下文中什么是“上下文”?它没有在您的代码或原始问题中的任何地方声明。 啊,好点@boutell。我确实假设这个问题是指使用 AWS Lambda,尽管它没有明确说明。我将编辑我的答案以反映这一点。上下文是 Lambda 特定的对象。如果使用 Lambda,则需要在回调函数中调用上下文完成方法(完成、成功、失败)以使其完成。如果这不是 Lambda 代码,则正在使用的程序在回调完成之前完成。 感谢您的澄清!您可能只想写“AWS Lambda”,因为 lambda 函数具有更一般的含义。【参考方案2】:我在所有 IAM 权利下都得到了完全相同的行为,但在我让它发挥作用之前浪费了一些时间。
如果您的 lambda 函数在 VPC 内运行,您必须为 S3 创建一个端点,如 this article from AWS blog 中所述。
如果您想查看更多详细信息,可以使用以下代码。而不是给回调一个保留对请求的引用并基本上观察它的事件(参见S3.putObject和AWS.Request的文档)。
var obj = s3.putObject(params);
obj.on('validate', (...args)=>args.unshift('validate'); console.log(...args);)
.on('build', (...args)=>args.unshift('build'); console.log(...args);)
.on('sign', (...args)=>args.unshift('sign'); console.log(...args);)
.on('send', (...args)=>args.unshift('send'); console.log(...args);)
.on('retry', (...args)=>args.unshift('retry'); console.log(...args);)
.on('extractError', (...args)=>args.unshift('extractError'); console.log(...args);)
.on('extractData', (...args)=>args.unshift('extractData'); console.log(...args);)
.on('success', (...args)=>args.unshift('success'); console.log(...args);)
.on('error', (...args)=>args.unshift('error'); console.log(...args);)
.on('complete', (...args)=>args.unshift('complete'); console.log(...args);)
.on('httpHeaders', (...args)=>args.unshift('httpHeaders'); console.log(...args);)
.on('httpData', (...args)=>args.unshift('httpData'); console.log(...args);)
.on('httpUploadProgress', (...args)=>args.unshift('httpUploadProgress'); console.log(...args);)
.on('httpDownloadProgress', (...args)=>args.unshift('httpDownloadProgress'); console.log(...args);)
.on('httpError', (...args)=>args.unshift('httpError'); console.log(...args);)
.on('httpDone', (...args)=>args.unshift('httpDone'); console.log(...args);)
.send();
通过这样做,我看到底层 HTTP 请求正在尝试访问存储桶的公共 url,这在 VPC 中是不可能的,除非你有端点:)。
这里还有另一篇关于从 VPC 访问 AWS 资源的帖子,同样来自 AWS blog。
【讨论】:
以上是关于S3.putObject - 回调永远不会被调用的主要内容,如果未能解决你的问题,请参考以下文章
解析:[PFFacebookUtils reauthorizeUser:] 回调永远不会被调用
OsX 中 USB HID API 的回调永远不会被游戏手柄或其他任何东西调用
从不同线程调用时,WCF Duplex 回调方法永远不会执行