4

So I tried to fetch data from dynamodb, using the below code, I am getting null and no log is showing after the query function is called.

I tried it locally, it is working locally, only through lambda function it is not working, I also checked if my role has the permission to read dynamodb, it does. So I am clueless on this

"use strict";

const config = require("./config");
const AWS = require("aws-sdk");

AWS.config.update({
  region: "us-east-1"
});
let dynamodb = new AWS.DynamoDB.DocumentClient({
  region: "us-east-1"
});

var getAnswerToQuestion = (questionKey, callback) => {

  var params = {
    TableName: "genral-questions-db",
    KeyConditionExpression: "#questionKey = :question",
    ExpressionAttributeNames: {
      "#questionKey": "question"
    },
    ExpressionAttributeValues: {
      ":question": String(questionKey)
    }
  };
  console.log("Trying to query dynamodb");

  dynamodb.query(params, (err, data) => {
    if(err) {
      console.log (err)
      callback(err);
    } else {
      console.log(data.Items);
      callback(data.Items[0]);
    }
  });
}

module.exports = {
  getAnswerToQuestion
};

logs:

Function Logs:
START RequestId: 6adeddbe-4925-4877-a2c0-d20576145224 Version: $LATEST
2019-09-22T17:35:30.088Z    6adeddbe-4925-4877-a2c0-d20576145224    event.bot.name=bcbsri
2019-09-22T17:35:30.088Z    6adeddbe-4925-4877-a2c0-d20576145224    dispatch userId=pn6yexoq87uej2evt9huhilc5f99bhb7, intentName=GenralQuestionIntent
2019-09-22T17:35:30.088Z    6adeddbe-4925-4877-a2c0-d20576145224    GenralQuestionIntent was called - Srinivas
2019-09-22T17:35:30.089Z    6adeddbe-4925-4877-a2c0-d20576145224    have to query the db hsa
2019-09-22T17:35:30.089Z    6adeddbe-4925-4877-a2c0-d20576145224    Trying to query dynamodb
END RequestId: 6adeddbe-4925-4877-a2c0-d20576145224
REPORT RequestId: 6adeddbe-4925-4877-a2c0-d20576145224  Duration: 596.83 ms Billed Duration: 600 ms Memory Size: 128 MB Max Memory Used: 76 MB  Init Duration: 193.27 ms    

not even getting error, it just does not give back any data. Please help me to resolve this issue

EDIT: here is the code from where I am trying to call the utils method(db)

module.exports =  function(intentRequest) { 
    return new Promise((resolve, reject) => {

        // Resolve question key
        const questionKey = intentRequest.currentIntent.slots.QuestionKey;

        let speechText;

        console.log('have to query the db', questionKey);

        utils.getAnswerToQuestion(questionKey, res => {
            if(res ) {
                speechText = res.answer;
            } else {
                speechText = "Sorry, details about " + questionKey + " was not found";
            }

            const response = {
                fullfilmentState: 'Fulfilled',
                message: { contentType: 'PlainText', content: speechText }
            };
            console.log(response);

            resolve(response);
            return lexResponses.close(intentRequest.sessionAttributes, response.fullfilmentState, response.message);
        });
    });
};
  • Provide where you use `getAnswerToQuestion` function. – hoangdv Sep 23 '19 at 04:19
  • I see you put the data to the first parameter of `callback` function. – hoangdv Sep 23 '19 at 04:53
  • I made changes to get the data from the callback in the second parameter (but null response), and the code you asked for has been edited – Srini Jagadeesh Sep 23 '19 at 05:13
  • It’s still an `async` issue. `return await new Promise` – Joey Kilpatrick Sep 23 '19 at 05:45
  • Maybe does not have any item with key value is `hsa` in your table. Just try get more info to debug, log you query param `console.log("Trying to query dynamodb", params);`. Don't do anything after `resolve(response);` – hoangdv Sep 23 '19 at 06:25
  • How are you deploying your code? Are you deploying it to the same account as the one used when running locally? – ElFitz Oct 07 '19 at 14:25

1 Answers1

7

I would bet that this is the most common problem that people see when using Node.js with Lambda.

When a Node.js Lambda reaches the end of the main thread, it ends all other threads. When it reaches the end of the handler, it stops all concurrent promises or async calls that are running.

To make sure that the lambda does not prematurely terminate those threads, wait until those promises are complete by using await.

In your case, use the .promise() method with any AWS requests and then await them:

try {
    const data = await dynamodb.query(params).promise();
    console.log(data.Items);
    callback(data.Items[0]);
}  catch (err) {
    console.log(err);
    callback(err);
}
Joey Kilpatrick
  • 1,394
  • 8
  • 20
  • I tried this, but it did not work, still not getting any data, even tried to create a promise for that function and tried async await while calling this function which resolves through promise, but it still did not work – Srini Jagadeesh Sep 23 '19 at 04:01