-1

I am writing a lambda function that's publishing to an SNS topic but it times out before any results come back, here's my function:

var AWS = require('aws-sdk'); // Used for calling SNS
var pg = require ('pg'); // Used to connect to Postgre

exports.handler = function (event, context) {
  'use strict';
  // Step 1 call database to get school hours
  var conn = "postgres://OMITTED:OMITTED@sOMITTED.ap-southeast-2.rds.amazonaws.com/slm_appdb"; // Save this in env variable
  var client = new pg.Client(conn);
  client.connect();

  // Step 1 call the database to get the hours
  const query = client.query("select * from find_all_students_school_hours();", (err,res) => {
    console.info('Query made',res.rows);
    res.rows.forEach(function(row){

      var command = {
        username: row.username,
        commands: {
          working_days: row.working_days || 'Mon-Fri',
          school_start_time: row.school_start_time || '08:00:00', // Save this in env variable
          school_end_time: row.school_end_time || '17:00:00' // Save this in env variable
        }
      };

      // Step 2 add command for agent by calling another lambda function through SNS
      var sns = new AWS.SNS();
      var params = {
        Message: JSON.stringify(command),
        Subject: 'Agent School Hours',
        TopicArn: 'arn:aws:sns:ap-southeast-2:OMITTED:add-command-for-agent-topic'
      }
      console.log('params',params);
      sns.publish(params, function(err,snsres){
        if(err){
          console.error('error',err);
        } else {
          console.info('published to sns',snsres);
        }
      });
    });

    context.done();
  });
};

and I have attached this policy to the lambda function:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "sns:*"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}

What I get in the logs is the params data but nothing after that, so i never reach console.error('error',err); or console.info('published to sns',snsres);, I gave it a one minute timeout and it still times out before it publishes and in the logs there are no errors coming from SNS (See image below), is there a way I can debug this to find out what's happening?

enter image description here

Mark B
  • 183,023
  • 24
  • 297
  • 295
Naguib Ihab
  • 4,259
  • 7
  • 44
  • 80

1 Answers1

1

You are calling context.done() without waiting for sns.publish to finish.

Remember that Javascript is asynchronous so while you are doing an I/O event (sns.publish) inside your res.rows.forEach() loop, context.done() will terminate your handler execution (and return) immediately without waiting for your SNS topic to be published.

Noel Llevares
  • 15,018
  • 3
  • 57
  • 81
  • It's outside of the loop though, so at least one SNS should be published before the event is finished, however, I tried removing it and extending the timeout to 5 minutes, it doesn't timeout any more but SNS doesn't receive any topics and doesn't reach either of the two logs inside the sns.publish – Naguib Ihab Nov 09 '17 at 21:59
  • No. It won't wait for `sns.publish` even if it is outside the loop. – Noel Llevares Nov 09 '17 at 22:51
  • Yeah you're right. I removed it anyway but I think the issue is in the NAT gateway, i'm checking that now. – Naguib Ihab Nov 09 '17 at 23:30