I'm trying to upload an image to S3 but when I call s3.putObject(params, callback), my callback never gets called and no errors are logged.
我正在尝试将图像上传到S3但是当我调用s3.putObject(params,callback)时,我的回调永远不会被调用,也不会记录任何错误。
Here's the relevant code:
这是相关的代码:
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);
});
Where params is { Key: 'e2f99bf3a321282cc7dfaef69fe8ca62.jpg', Body: {imageData parsed from request using node-multiparty}, ContentLength: 27802, ContentType: 'image/jpeg', }
其中params是{Key:'e2f99bf3a321282cc7dfaef69fe8ca62.jpg',正文:{imageData使用node-multiparty从请求解析},ContentLength:27802,ContentType:'image / jpeg',}
I have verified that this.s3 is valid and typeof this.s3.putObject is function as expected.
我已经验证this.s3是有效的,并且this.s3.ObjectObject的typeof按预期运行。
2 个解决方案
#1
5
If this code is being used for a lambda function you need to add context.done() within the putObject's callback function like so:
如果此代码用于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();
});
This forces the execution to wait until the callback is filled before it exits. For this to work you will also need to remove any context.succeed or context.done from the main handler if you have one there.
这会强制执行等待回调在退出之前完成。为此,您还需要从主处理程序中删除任何context.succeed或context.done(如果有的话)。
#2
0
I got exactly the same behavior with all the IAM rights, and lost a bit of time before I got it to work.
我对所有IAM权利都有完全相同的行为,并且在我开始工作之前失去了一点时间。
If your lambda function runs inside a VPC you have to create an endpoint for S3 as describe in this article from AWS blog.
如果您的lambda函数在VPC内部运行,则必须为AWS创建一个端点,如AWS博客中的本文所述。
If you want to see more in details where it hangs, you can use the following code. Instead of giving a callback a keep the reference on the request and basically observe its events (see the documentation of S3.putObject and AWS.Request).
如果要查看挂起的详细信息,可以使用以下代码。不要给出回调,而是保留对请求的引用并基本观察它的事件(参见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();
By doing so I got to see the underlying HTTP request was trying to reach the public urls of the bucket, which is not possible from a VPC unless you have the endpoint :).
通过这样做,我得到了底层的HTTP请求试图到达桶的公共URL,除非你有端点,否则这是不可能的。
Here is also another post about accessing AWS ressources from a VPC also from AWS blog.
这里还有一篇关于从AWS博客也从VPC访问AWS资源的帖子。
#1
5
If this code is being used for a lambda function you need to add context.done() within the putObject's callback function like so:
如果此代码用于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();
});
This forces the execution to wait until the callback is filled before it exits. For this to work you will also need to remove any context.succeed or context.done from the main handler if you have one there.
这会强制执行等待回调在退出之前完成。为此,您还需要从主处理程序中删除任何context.succeed或context.done(如果有的话)。
#2
0
I got exactly the same behavior with all the IAM rights, and lost a bit of time before I got it to work.
我对所有IAM权利都有完全相同的行为,并且在我开始工作之前失去了一点时间。
If your lambda function runs inside a VPC you have to create an endpoint for S3 as describe in this article from AWS blog.
如果您的lambda函数在VPC内部运行,则必须为AWS创建一个端点,如AWS博客中的本文所述。
If you want to see more in details where it hangs, you can use the following code. Instead of giving a callback a keep the reference on the request and basically observe its events (see the documentation of S3.putObject and AWS.Request).
如果要查看挂起的详细信息,可以使用以下代码。不要给出回调,而是保留对请求的引用并基本观察它的事件(参见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();
By doing so I got to see the underlying HTTP request was trying to reach the public urls of the bucket, which is not possible from a VPC unless you have the endpoint :).
通过这样做,我得到了底层的HTTP请求试图到达桶的公共URL,除非你有端点,否则这是不可能的。
Here is also another post about accessing AWS ressources from a VPC also from AWS blog.
这里还有一篇关于从AWS博客也从VPC访问AWS资源的帖子。