1

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.

2
  • I found that if I remove the callback reference that the Sequelize code runs fine. Commented Aug 25, 2016 at 15:25
  • I have the same problem but none of the answer below and removing the callback reference works for me. Commented Sep 24, 2021 at 7:51

2 Answers 2

4

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")
}
Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.