I have a very simple lambda function, in Javascript, that fetches a JSON from dweet.io and stores it in a DynamoDB database. However, I am having issues with the function ending before the data has been stored, and I can not figure out what I am doing wrong.
The Function
const http = require("http");
const AWS = require("aws-sdk");
let url = "http://dweet.io/get/latest/dweet/for/test";
exports.handler = async function (event) {
const promise = new Promise(async function (resolve, reject) {
http
.get(url, (res) => {
res.setEncoding("utf8");
res.on("data", async function (chunk) {
console.log("Body: ", chunk);
var data = JSON.parse(chunk);
console.log("Data:", data["with"][0]);
await saveToDynamoDb(data["with"][0]);
console.log("Done saving");
});
resolve(res.statusCode);
})
.on("error", (e) => {
reject(Error(e));
});
});
return promise;
};
async function saveToDynamoDb(data) {
var dynamodb = new AWS.DynamoDB();
var params = {
Item: {
item: {
S: data.thing,
},
time: {
S: "" Date.now(),
},
lat: {
S: "" data.content.lat,
},
long: {
S: "" data.content.long,
},
speed: {
S: "" data.content.speed,
},
head: {
S: "" data.content.head,
},
alt: {
S: "" data.content.alt,
},
temp: {
S: "" data.content.temp,
},
batt: {
S: "" data.content.batt,
},
},
ReturnConsumedCapacity: "TOTAL",
TableName: "BoxTrackingEvents",
};
console.log("Save requset: ", params);
try {
const data = await dynamodb
.putItem(params, function (err, data) {
if (err) {
console.log("Error Saving:", err, err.stack);
} else {
console.log("Saving done:", data);
}
})
.promise();
console.log("Item entered successfully:", data);
} catch (err) {
console.log("Error: ", err);
}
return "ok";
}
The Function logs
Function Logs
START RequestId: e7ebceff-560e-4a94-bc4f-3f1ae085d2ba Version: $LATEST
2021-10-15T03:40:15.217Z e7ebceff-560e-4a94-bc4f-3f1ae085d2ba INFO Body: {"this":"succeeded","by":"getting","the":"dweets","with":[{"thing":"test","created":"2021-10-15T03:38:03.138Z","content":{"lat":36.139095,"long":-115.30141,"speed":0,"head":357,"alt":840.1,"temp":31.81,"batt":4121}}]}
2021-10-15T03:40:15.245Z e7ebceff-560e-4a94-bc4f-3f1ae085d2ba INFO Data: {
thing: 'test',
created: '2021-10-15T03:38:03.138Z',
content: {
lat: 36.139095,
long: -115.30141,
speed: 0,
head: 357,
alt: 840.1,
temp: 31.81,
batt: 4121
}
}
2021-10-15T03:40:15.383Z e7ebceff-560e-4a94-bc4f-3f1ae085d2ba INFO Save requset: {
Item: {
item: { S: 'test' },
time: { S: '1634269215382' },
lat: { S: '36.139095' },
long: { S: '-115.30141' },
speed: { S: '0' },
head: { S: '357' },
alt: { S: '840.1' },
temp: { S: '31.81' },
batt: { S: '4121' }
},
ReturnConsumedCapacity: 'TOTAL',
TableName: 'BoxTrackingEvents'
}
END RequestId: e7ebceff-560e-4a94-bc4f-3f1ae085d2ba
REPORT RequestId: e7ebceff-560e-4a94-bc4f-3f1ae085d2ba Duration: 966.23 ms Billed Duration: 967 ms Memory Size: 128 MB Max Memory Used: 76 MB Init Duration: 501.88 ms
Request ID
e7ebceff-560e-4a94-bc4f-3f1ae085d2ba
CodePudding user response:
The problem is that you are resolving before the "data" event callback has finished.
Move the resolve
inside the callback:
res.on("data", async function (chunk) {
console.log("Body: ", chunk);
var data = JSON.parse(chunk);
console.log("Data:", data["with"][0]);
await saveToDynamoDb(data["with"][0]);
console.log("Done saving");
resolve(res.statusCode);
});
There might also be an issue with the double promise of the exported function: one implied by the async
and once from the returned promise. I think you may want to drop that outer async
keyword.