AWS Lambda using s3 getObject function nothing happening
The call to s3.getObject
is an asynchronous call. The execution of the code continues while the s3
code is run. You need to explicitly await
for the call's promise to resolve.
This is how you would do that (note the change in the s3.getObject
call):
const AWS = require('aws-sdk');
const s3 = new AWS.S3();
exports.handler = async (event) => {
var params = {
Bucket: <bucket>,
Key: <key>,
};
const data = await s3.getObject(params).promise();
const response = {
statusCode: 200,
body: JSON.stringify(data),
};
return response;
};
You can use a try/catch
block for error handling.
The important thing to understand here is the timing of the execution. The mainline code in your function is called sequentially when the lambda is invoked. The callback function that you pass to the s3.getObject
call is called when a response from S3 arrives, long after your lambda had finished its execution.
Your return
call is executed before the callback runs, and hence you see the result of JSON.strigify(responseMsg)
where responseMsg
holds the initial value you gave it, which is the empty string ''
.
BermudaLamb
Senior-level Information Technology Architect with solid experience in strategic planning, project management, and enterprise-wide systems architecture. Successful background of leveraging existing technologies and systems to increase comipetitive advantage, and the introduction of new technologies to improve productivity while reducing workflow bottle-necks. Able to translate abstract concepts into practical, feature-rich solutions. Proven track record of developing, implementing and converting to ERP and CRM systems.
Updated on June 14, 2022Comments
-
BermudaLamb almost 2 years
This is the node.js code using the inline editor:
const AWS = require('aws-sdk'); const s3 = new AWS.S3(); console.log('Loading function'); exports.handler = async (event) => { // TODO implement var responseMsg = ''; var bucket = ''; var key = ''; if ('Records' in event) { var s3Data = event.Records[0].s3; console.log('s3Data: ' + JSON.stringify(s3Data)); bucket = s3Data.bucket.name; key = s3Data.object.key; } console.log('Bucket:' + bucket); console.log('Key:' + key); var params = { Bucket: bucket, Key: key }; console.log('Params:' + JSON.stringify(params)); s3.getObject(params, function (err, data) { console.log('getObject'); if (err) { console.log(err, err.stack); return err; } responseMsg = data; }); const response = { statusCode: 200, body: JSON.stringify(responseMsg), }; return response; };
I know that the key and bucket I'm testing with exists in my S3 console. I know that I can access the them using C# in LINQPad.
When I run this, I'm not getting any errors. I'm getting an empty string in the body of response, rather than the content of the object. I'm also not getting any log messages from within the s3.getObject.
-
muasif80 over 3 yearsHow to handle multiple getobject requests in lambda like this.?
-
muasif80 over 3 yearsOk so I was trying to use
forEach
to loop through the keys and callinggetobject
but it did not work as it involves a callback function. Although simple for-loop has worked in doing multiplegetobject
calls and then collecting their results into an array -
Kalev over 3 yearsYeah, a
forEach
won't work (at least not the naive approach). What I'd do instead is useArray.map()
to produce a list of promises, and usePromise.all()
on the resulting list of promises. -
muasif80 over 3 yearsOk. This
Promise.all
i tried but may be missing something it also did not work. Will check it again sometime. Thanks.