AWS S3 putObject callback not firing

Viewed 7626

I have a lambda function trying to place an mp3 file into an S3 bucket, however I am not seeing my file uploaded and more strangely do not see any logging/response from the callback.

My lambda/s3 bucket are all on the same AWS account and the bucket name is definitely correct.

Is there something I'm missing here? Or any explanation why my callback is not being fired?

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

    // prior setup

    console.log('about to putObject on s3');

    const s3BucketData = {
        Bucket: 'media-files',
        Key: fileName,
        Body: fileDataBuffer,
        ContentType: 'audio/mp3'
    };

    await s3.putObject(s3BucketData, (err, data) => {
        console.log('putObject callback executing');
        if (err) {
            console.log('err occurred storing to s3: ', err)
        } else{
            console.log(`${fileName} succuessfully uploaded`);
        }
        context.done();
    });
};
2 Answers

First of all, it's a bad practice to stick your methods inside of the handler function. Second of all you have some issue with your runtime. I mean that you choosed node 8.10 with await/async support, but you still trying to use callbacks. I have some comments for you. I hope it's going to help you.

1) You can simple do that:

export async function handler(event)
{
    // body of your function
};

2) AWS services promisified. You have to re-write your s3 method. Take a look at the following snippet. And I've got a question. Are sure that you have to use putObject method instead of upload?

try
{
 let s3= new AWS.S3({ region: process.env.AWS_REGION, apiVersion: '2006-03-01' });
 let params = 
{
   Bucket: //aws s3 bucket location (a full path),
   Key: //file name/key,
   Body: //entity to upload,
   ACL: 'public-read' // access policy,
   ContentType: 'audio/mp3' 
};

 let s3Response = await s3.upload(params).promise();
// request successed
 console.log(`File uploaded to S3 at ${s3Response.Bucket} bucket. File 
 location: ${s3Response.Location}`);

 return s3Response.Location; 
}
// request failed
catch (ex)
{
 console.error(ex);
}

If you want to stick callbacks then:

s3.upload(params, (err, data) => 
{
  console.log('putObject callback executing');
  if (err) 
  {
     console.error('err occurred storing to s3: ', err);

     return ;
  } 
  console.log(`${fileName} succuessfully uploaded`);

  return data;
});

I hope you'll find this helpfull. Cheers!

Below example help you to convert putObject to promise

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

    console.log('about to putObject on s3');

    const s3BucketData = {
        Bucket: 'media-files',
        Key: fileName,
        Body: fileDataBuffer,
        ContentType: 'audio/mp3'
    };

   S3.putObject(s3BucketData).promise()
      .then(data => {
        console.log('complete:PUT Object',data);
         callback(null, data);
      })
      .catch(err => {
        console.log('failure:PUT Object', err);
         callback(err);
      });
};
Related