WHOATEMYNOODLES
WHOATEMYNOODLES

Reputation: 2643

Lambda - Nodejs SDK s3.upload() is not being triggered

Been debugging an entire day and still can't figure out why my s3.upload() method is not being called inside my lambda function. Someone please help

const AWS = require('aws-sdk');
let s3= new AWS.S3();

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


        var message_body = JSON.parse(event.body);

        let encodedImage = message_body.base64;
        let decodedImage = Buffer.from(encodedImage, 'base64');

        var params = {
            "Body": decodedImage,
            "Bucket": "testbucket1-bucket",
            "Key": "testkey1.jpg"  
        };

        console.log("function triggered. ");


        s3.upload(params).promise()
      .then(data => {
        console.log('complete:PUT Object',data);
         callback(null, data);
      })
      .catch(err => {
        console.log('failure:PUT Object', err);
         callback(err);
      });

};

In Cloudwatch, there are no errors in the entire function. I've made sure the function has access to s3, the bucket is public, and the bucket name is correct numerous times. It just times out after 30 seconds. Neither of the s3.upload() callback methods are being fired and I can't for the life of me figure out why.

Issue Identified

....I just figured out the problem after wasting so much time. My Lambda function had a VPC that didn't grant access to S3.... Now the function is not timing out, and the upload finally is working.

Upvotes: 0

Views: 670

Answers (2)

Arun Kamalanathan
Arun Kamalanathan

Reputation: 8603

the lambda works perfectly fine for me.

const fs = require('fs');
const AWS = require('aws-sdk');
const s3 = new AWS.S3();

exports.handler = async (event) => {
    // TODO implement
    var userData = {};

    console.log('1')
    return new Promise((resolve, reject) => {

        console.log('2 type of body: ', typeof event.body);
        const body = JSON.parse(event.body)
        console.log('2.1 body.base64: ', body.base64);

        let decodedImage = Buffer.from(body.base64, 'base64');
        var params = {
            "Body": decodedImage,
            "Bucket": "stackoverflow-help",
            "Key": "testkey1.jpg"  
        };

        console.log('3')

        s3.upload(params, function(err, data){
            console.log('4')

           if(err){
               console.log("Upload Failed");
              throw err;
           }else{
               console.log("Upload worked");
              let response = "event_photo";
              userData[response] = "SUCCESS RECIEVING EVENT";
              var jsonString = JSON.stringify(userData);
              resolve({statusCode:200, body: jsonString});
           }
        });
    });
};

Please check if you have covered the below.

  1. Create the lambda
  2. Give lambda permission to write put to s3
  3. create an api gateway endpoint with POST or PUT with lambda proxy integration
  4. configured the api gateway to invoke the lambda

Testing

  • when testing the api gateway from aws console, For the request body, you have to give an base64 encoded string of the image

  • when testing from postman, make sure, you select raw under the Body and copy paste the base64 encoded string of the image

hope this helps.

Upvotes: 1

elarcoiris
elarcoiris

Reputation: 1976

Firstly, if it's a private bucket, you initialise its authorisation details. Allowing uploads to a public s3 bucket without regulation isn't advised.

s3.config.update({
    region: 'ap-southeast-2',
    accessKeyId: process.env.ACCESS_KEY,
    secretAccessKey: process.env.SECRET_KEY
});

Otherwise, you fulfil the s3 upload promise, and here's the async/await way to do it:

try {
    await s3.headObject(params).promise();
    console.log("File found");
    try {
        await s3.upload(params).promise();
        console.log("uploaded successfully");
    }
    catch (error) {
        console.log(error);
        res.status(500).send(error.message);
    }
}
catch (error) {
    console.log(error);
    res.status(500).send(error.message);
} 

Let me know if this works for you.

Upvotes: 0

Related Questions