0

I am writing an aws lambda function to get data from 3 sources and return it in json format. I am attempting to use promises to get it done. However my function always times out even though the three procedures run correctly it does not seem to return the result.

I have been trying to reorder the promises and have removed a couple to see if they fail.

it's this promise specifically

.then(function(clientinfo) {
        return new Promise((resolve, reject) => { // (*)
            pool.getConnection(function(err, connection) {
                if (err) {
                    console.log(err);
                }
                connection.query('SELECT * FROM mautic.leads where email = "test@test.com"', function (error, results, fields) {
                    connection.release();
                    // Handle error after the release.
                    if (error) throw error;
                    else
                    console.log(results);
                    console.log('send results');
                    clientinfo.mydata = results;
                    callback(clientinfo);
                });
            });  
        });
    })
function get_user(event, callback) {

    console.log('START');

    new Promise( function (resolve, reject) {
        dynamo.query({
            TableName : 'TransactionFingerprint',
            KeyConditionExpression : "emailmtcid = :emailmtcid",
            ExpressionAttributeValues : {
                ":emailmtcid": event.queryStringParameters.id
            },
            Limit : 1
        }, function(err, data) {
            if (err) {
              console.log('error','reading dynamodb failed: '+err);
              reject(err);
            }
            if (data.Count == '0') {
              console.log('NOT FOUND');
              update_user(url, sid, function(json){ callback(json) });
            } else { 
                console.log('FOUND IN DYNAMO');
                const dyntable = {
                    "TableName": "TransactionFingerprint",
                    "Item": { 
                        "Id": data.Items[0].emailmtcid
                    }
                };
                console.log("dynamodb");
                console.log(dyntable);
                resolve(dyntable) ;
            }
        });
    })
    .then(function(dyntable) {
        return new Promise((resolve, reject) => { // (*)
            conn.login(salesforceLogin, salesforcePass, function(err, res) {
                if (err) {
                    console.log(err);
                }
                conn.query("SELECT FirstName,LastName,PersonEmail,silverpop__Silverpop_RecipientID__pc from Account WHERE PersonEmail = 'test@test.com'", 
                    function(err, res) {
                        if (err) { 
                            console.log(res + 'SF2 RESPONSE');  
                        }
                    var sfinfo = res['records'];
                    var clientinfo = {};
                    clientinfo.data = sfinfo;
                    console.log('salesforce query');
                    console.log(sfinfo);
                    clientinfo.dyndata = dyntable;
                    resolve(clientinfo);
                });
            });
        });
    })
    .then(function(clientinfo) {
        // return new Promise((resolve, reject) => { // (*)
            pool.getConnection(function(err, connection) {
                if (err) {
                    console.log(err);
                }
                connection.query('SELECT * FROM mautic.leads where email = "test@test.com"', function (error, results, fields) {
                    connection.release();
                    // Handle error after the release.
                    if (error) throw error;
                    else
                    console.log(results);
                    console.log('send results');
                    clientinfo.mydata = results;
                    callback(clientinfo);
                });
            });  
        // });
    });
}

get_user(event, response => done(null, response));

Hopefully i will return all results from all three data sources in one json object. **EDIT I removed the callbacks inside the .then()

scottmont
  • 39
  • 6
  • 1
    The default lambda timeout is 3 seconds. try to increase the timeout. – Amit Baranes Sep 26 '19 at 19:12
  • 1
    You won't get the desired results mixing plain callbacks inside a `.then()` handler because nothing will wait for the callbacks to finish. – jfriend00 Sep 26 '19 at 19:41
  • i did that it just runs the maximum time i give then. the callback doesn't seem to be happening . – scottmont Sep 26 '19 at 19:41
  • In the `if (data.Count == '0')` case, you are never resolving the promise. – Bergi Sep 27 '19 at 03:24
  • This is why you should use a library like Bluebird that can promisify APIs for you, so you don't have to use the `Promise` constructor. As @Bergi mentioned the promise is unresolved in one case, and you're also creating unnecessary promises inside the `then`. – Logan Pickup Sep 27 '19 at 03:30
  • Suggestions: 1. Rather than have `get_user()` accept a callback, arrange for it to return a promise and call with `get_user(event.queryStringParameters.id) .then(response => done(null, response));` – Roamer-1888 Sep 29 '19 at 21:10
  • 2. In `get_user()`, rather than attempt one overall promisifation (which is indeed possible), it's more typical to [promisify individual functions/methods at the lowest level](https://stackoverflow.com/questions/22519784/how-do-i-convert-an-existing-callback-api-to-promises) thus allowing the application logic to be less volumous and simpler to follow. Here, you would promisify : - dynamo.query(), - conn.login(), - conn.query(), - update_user(). – Roamer-1888 Sep 29 '19 at 21:10
  • 3. In constructing your promise chain in `get_user()` you would need to master [how to access previous promise results in a .then() chain](https://stackoverflow.com/questions/28250680/how-do-i-access-previous-promise-results-in-a-then-chain) – Roamer-1888 Sep 29 '19 at 21:10

1 Answers1

0

I figured out the issue.

The pool.connection I am using. Though i use connection.release() I still need to close the pool for the lambda to complete.

 if (err) {
   console.log(err)
 }
 });

Thank you all for your comments and help.

scottmont
  • 39
  • 6