S3.putObject - callback never called

I am trying to upload an image to S3, but when I call s3.putObject (params, callback), my callback is never called and no errors are logged.

Here is 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); }); 

If the parameters are { Key: 'e2f99bf3a321282cc7dfaef69fe8ca62.jpg', Body: {imageData parsed from request using node-multiparty}, ContentLength: 27802, ContentType: 'image/jpeg', }

I checked that this.s3 is valid and typeof this.s3.putObject is functioning properly.

+6
source share
2 answers

If this code is used for a lambda function, you need to add context.done () to the putObject callback function as follows:

  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 causes execution to wait until the callback is filled before it leaves. For this, you will also need to remove any context.succeed or context.done from the main handler, if you have one there.

+3
source

I got exactly the same behavior with all IAM rights and lost a little time before I earned it.

If your lambda function works inside a VPC, you need to create an endpoint for S3 , as described in this AWS blog post .

If you want to see more details where it hangs, you can use the following code. Instead of giving a callback, keep a link to the request and basically watch its events (see the S3.putObject and AWS.Request documentation ).

 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(); 

In this way, I realized that the main HTTP request is trying to reach the public bucket urls, which is not possible from VPC unless you have an endpoint :).

Here's another post about accessing AWS ressources from VPCs also from the AWS Blog .

0
source

Source: https://habr.com/ru/post/987349/


All Articles