Reputation: 57
I have a lambda function that is triggered whenever something is saved in my s3 bucket,
the aim is to read the metadata of a JSON file and insert rows in a dynamoDB table;
for instance a training period starts on the june the 1st and end june 8th and training days are Monday, Wednesday and Friday thus the lambda should insert 4 rows ( 1st, 3rd, 5th, 8th of june)
so far only one row is inserted and then the error occurs and it crashes
The function is triggered well but this error message occurs sometimes.
{
"errorType": "TypeError",
"errorMessage": "Cannot read property 'bucket' of undefined",
"stack": [
"TypeError: Cannot read property 'bucket' of undefined",
" at Runtime.exports.handler (/var/task/index.js:26:44)",
" at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"
]
}
here is my function
let AWS = require('aws-sdk');
let s3 = new AWS.S3();
let moment = require('moment');
let uuid = require('node-uuid');
let apiSportmTrainingTableName = process.env.API_SPORTM_TRAININGTABLE_NAME
let dynamodb = new AWS.DynamoDB.DocumentClient();
exports.handler = async (event, context) => {
//eslint-disable-line
const Bucket = await event.Records[0].s3.bucket.name;
const Key = await event.Records[0].s3.object.key;
const objectHead = await s3.headObject({Bucket, Key}).promise();
let start = moment(new Date(objectHead.Metadata.trainingstart), "YYYY-MM-DD");
let end = moment(new Date(objectHead.Metadata.trainingend), "YYYY-MM-DD");
let days = JSON.parse("[" + objectHead.Metadata.trainingdays + "]");
try {
for (let m = moment(start); m.diff(end, 'days') <= 0; m.add(1, 'days')) {
for (const e of days) {
if (moment(m).day() === e) {
let params = {
TableName: apiSportmTrainingTableName,
Item: {
"id": uuid.v1(),
"trainingDate": moment(m).format('YYYY-MM-DD'),
"statut": true,
"athleteCategory": objectHead.Metadata.trainingmembercategory,
"trainingTime": objectHead.Metadata.trainingtime
}
};
return await dynamodb.put(params).promise();
}
}
}
} catch (err) {
console.error('Error', err);
return;
}
context.done(null, 'Successfully processed DynamoDB record'); // SUCCESS with message
};
when the event logs it looks like that
Records: [
{
eventVersion: '2.1',
eventSource: 'aws:s3',
awsRegion: 'us-east-1',
eventTime: '2020-05-29T18:34:53.250Z',
eventName: 'ObjectCreated:Put',
userIdentity: [Object],
requestParameters: [Object],
responseElements: [Object],
s3: [Object]
}
]
}
```
that a part of logs it fails and then works and then it keeps trying and fail
[logs][1]
[1]: https://i.sstatic.net/Sj5C7.png
Upvotes: 0
Views: 4751
Reputation: 576
You are using return
after inserting data into DynamoDB:
return await dynamodb.put(params).promise();
This returns the result of the DynamoDB operations as the result of the Lambda function, which terminated the execution. This explains why only one record is inserted into DynamoDB. I'd try to remove the return
and see if that also removes the error (best guess on my part: the returned value somehow causes another execution with it, but this time missing the S3 event, thus event.Records[0].s3
will be undefined).
Upvotes: 1