Reputation: 154
I'm trying to write a lambda function that is triggered whenever a new image is written to an S3 bucket. The trigger is already setup using the correct S3 bucket so I know that's not the issue.
The lambda function itself has the roles s3:GetObject and dynamodb.* (which should be full access for DynamoDB writes).
The goal here is to simply write to a table that I've already created named 'art' and insert a primary key value (imageTitle) which i'm trying to obtain in var imageName
. Then I want to assign to that key an attribute which is the url of that image, which I'm storing in var url
.
This is just a simple exercise I'm trying to get down so that I can move on to more complex DB writes. But as of right now, I'm not getting anything written to the art
table, even though I am adding new objects to the S3 bucket which sets off the trigger. Is it possible that the lambda function isn't deployed? I wrote it directly in the inline editor of the Lambda Console and saved it.
Here's the code:
const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient({region: 'us-east-1'});
const s3 = new AWS.S3();
exports.handler = async (event, context, callback) => {
//var sourceBucket = event.Records[0].s3.bucket.name;
var sourceKey = event.Records[0].s3.object.key;
var imageName = sourceKey.stringify;
//generate imageURL
var url = "https://s3.amazonaws.com/myapp-20181030214040-deployment/public/" + imageName;
var params = {
TableName : 'art',
Item: {
imageTitle: imageName,
imageURL: url
}
};
docClient.put(params, function(err, data) {
if (err) console.log(err);
else console.log(data);
});
};
Upvotes: 0
Views: 1264
Reputation: 8482
The problem here is that you're using an async lambda but returning nothing that is awaitable. This means that your lambda is terminating before the docClient.put
operation is sent.
With an async handler you need to await and return, for example you could change this snippet to:
const data = await docClient.put(params).promise();
return data;
Or instead you could use the callback
approach (note the signature of the handler does not contain async
anymore):
exports.handler = (event, context, callback) => {
// ... the rest of the code as was ...
docClient.put(params, function(err, data) {
if (err) {
console.log(err);
callback(err); // return 'lambda invoke failed because of the error' - will cause s3 to retry three times.
} else {
console.log(data);
callback(null, data); // return 'nothing failed'; n.b. the s3 trigger ignores whatever you return.
}
});
};
Upvotes: 6