Reputation: 131
I've got Sequelize-based code that runs fine in a Node.js project. I moved that code into an AWS Lambda handler and am testing it with the node-lambda module. Now the Sequelize code seems to be skipped. I'm not sure if the promise isn't being handled before the Lambda finishes, or if I'm missing something else. The following code skips the "during" console.log as shown in the output below.
var models = require('./models');
exports.handler = function( event, context, callback ) {
console.log("Before");
var body = JSON.parse(event.body);
// Find the device ID from the devices table
models.Device.findOne({where: {device_uuid: body.device_uuid}, attributes: ['id']}).then(function(device) {
console.log("During");
// Make sure that we got a device back
if (device === null) {
console.log("Device not found - could not insert data");
return;
}
else {
console.log("Device found, inserting data - " + body.device_uuid);
//Insert the data for this device
models.Data.create({
device_id: device.id,
data: body.data
});
}
});
console.log("After");
callback(null, "{\"status\": \"success\"}");
}
Yields...
Before
After
Success:
"{\"status\": \"success\"}"
Any ideas on where I'm going wrong? I'm using Node v5.9.0.
Upvotes: 1
Views: 2091
Reputation: 5446
Spent me almost a day to figure out what's wrong as I have the exact same issue.
Turn out I need to put await to those function which interact with database using sequelize, else Lambda will just exits.
module.exports.v2BlacklistEmails = async (event, context) => {
try {
const message = JSON.parse(event.Records[0].Sns.Message)
switch (message.notificationType) {
case "Bounce":
handleBounce(message);
break;
}
} catch (err) {
console.log("Error processing event: " + err.stack)
}
}
function handleBounce(message) {
const messageId = message.mail.messageId
const addresses = message.bounce.bouncedRecipients.map(function (recipient) {
return recipient.emailAddress
})
const bounceType = message.bounce.bounceType
console.log("Message " + messageId + " bounced when sending to " + addresses.join(", ") + ". Bounce type: " + bounceType)
for (var i = 0; i < addresses.length; i++) {
if (addresses[i] !== process.env.BOUNCE_EMAIL_AU && addresses[i] !== process.env.BOUNCE_EMAIL_NZ) {
utils.blacklistEmailsIntoDB(decryptedUser, decryptedPassword, addresses[i])
} else {
console.log("Mailbox " + addresses[i] + " maybe full, please check.")
}
}
}
So I have to put await at:
handleBounce(message);
and
utils.blacklistEmailsIntoDB(decryptedUser, decryptedPassword, addresses[i])
Of course you need to put async to those function as well.
Upvotes: 0
Reputation: 114
I just started playing with apigateway / lambda and sequelize, but as far as I know of node and sequelize, the callback should be inside the "then" block.
Yesterday found that if you're using callback(null, successData), the performance was really poor (>11 secs on a Select top 1). Had to change the flag context.callbackWaitsForEmptyEventLoop = false and now the api call takes 24ms.
//Important to improve performance!
context.callbackWaitsForEmptyEventLoop = false
// Find the device ID from the devices table
models.Device.findOne({where: {device_uuid: body.device_uuid}, attributes: ['id']}).then(function(device) {
console.log("During");
// Make sure that we got a device back
if (device === null) {
callback(new Error("Device not found - could not insert data"))
}
else {
console.log("Device found, inserting data - " + body.device_uuid);
//Insert the data for this device
models.Data.create({
device_id: device.id,
data: body.data
})
.then(function(insertedData){
callback(null, insertedData.toJSON())
})
.catch(function(error){
callback( new Error("Error creating")
})
}
})
console.log("After")
}
Upvotes: 4