6

I am attempting to list an S3 bucket from within my node.js (8.10) lambda function.

When I run the function below (in Lambda), I see "Checkpoint 1" and "Checkpoint 2" in my logs, but I don't see any logging from the listObjectsV2 call, neither error nor data. My timeout is set to 10 seconds and I am not seeing any log entries for timeouts, either. I think I may missing something about using asynchronous functions in lambda?

const AWS = require('aws-sdk');
const s3 = new AWS.S3({apiVersion: '2006-03-01'});

exports.handler = async (event, context) => {

    // console.log('Received event:', JSON.stringify(event, null, 2));

    var params = { 
        Bucket: 'bucket-name'
    }

    console.log("Checkpoint 1");

    s3.listObjectsV2(params, function (err, data) {
        if (err) {
            console.log(err, err.stack);
        } else {
            console.log(data);
        }
    });


    console.log("Checkpoint 2");

};

Can someone point me in the right direction for finding my error here?

3
  • Any chance that your Lambda function is timing out before the list can be printed? CloudWatch Logs would show a timeout. Note that Lambda default execution timeout is 3 seconds. Commented Aug 11, 2018 at 22:54
  • I haven't seen any CloudWatch log entries for timeouts. I should have noted above that I did up the timeout to 10 seconds, too. Commented Aug 11, 2018 at 23:26
  • 2
    You should be returning a promise, should you not? Commented Aug 11, 2018 at 23:37

2 Answers 2

13

Not only you need to return a promise, you also need to await on it, otherwise it has no effect. This is because your handler is async, meaning it will return a promise anyways. This means that if you don't await on the code you want to execute, it's very likely that Lambda will terminate before the promise is ever resolved.

Your code should look like this:

const AWS = require('aws-sdk');
const s3 = new AWS.S3({apiVersion: '2006-03-01'});

exports.handler = async (event, context) => {

    // console.log('Received event:', JSON.stringify(event, null, 2));

    var params = { 
        Bucket: 'bucket-name'
    }

    console.log("Checkpoint 1");

    let s3Objects

    try {
       s3Objects = await s3.listObjectsV2(params).promise();
       console.log(s3Objects)
    } catch (e) {
       console.log(e)
    }


    console.log("Checkpoint 2");

    // Assuming you're using API Gateway
    return {
        statusCode: 200,
        body: JSON.stringify(s3Objects || {message: 'No objects found in s3 bucket'})
    }

};
Sign up to request clarification or add additional context in comments.

Comments

1

AWS SDK can return a promise, just add .promise() to your function.

s3.listObjectsV2(params).promise();

1 Comment

You're mixing the concepts of promises and callbacks. If you use .promise() then you don't need to provide the (err,data) callback

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.