AWS Lambda Function always returns null (Node/Javascript)?

Z_z_Z picture Z_z_Z · Jul 21, 2018 · Viewed 8.8k times · Source

I have a simple Lambda function that is supposed to take event data and send a message to an SNS topic.

Runtime is Node.js 8.10.

Here's my Lambda code in its entirety:

const AWS = require("aws-sdk");

exports.handler = async (event) => {

const sns = new AWS.SNS();

const emailBody = 
`
New Message

From: ${event.name}
Contact: ${event.contact}

Message: ${event.message}
`;

const snsMessageParams = {
    TopicArn: process.env.snsTopicArn,
    Message: emailBody
};

sns.publish(snsMessageParams, (err, data) => {
    if(err) {
        return err;
    } else {
        return data;
    }
  });
};

Every time I run the function I always get null in response. No error is returned, but I never get a message in my email from SNS, so there is something wrong here. I just can't figure out what.

I am able to successfully publish a message to my SNS topic from the SNS console, and from the Node SDK on my local computer. These work perfectly. I have checked that the snsTopicArn in my env variables is correct by copying and pasting it directly from my successful local code and the SNS console.

I have an Execution Role on my Lambda function that should allow me to publish to SNS on any topic in my account. I chose the default "SNSPublish" option when configuring the role for Lambda just to test everything. But for reference, here is the policy for my Execution Role:

{
  "roleName": <MyRoleName>,
  "policies": [
    {
       "document": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": [
                "sns:Publish"
              ],
              "Resource": "arn:aws:sns:*:*:*"
            }
          ]
        }
    ...
}

What is going wrong here? Any help is definitely appreciated.

Answer

Z_z_Z picture Z_z_Z · Jul 22, 2018

Ok, so I figured it out.

There were two issues. The first is that I wasn't using the "callback" parameter that is used implicitly by Lambda for Node. The second was that the function was async by default, so it was expecting an "await" somewhere later. I decided just to remove the "async" and let it run synchronously since it is just a simple function and doesn't need it anyway.

Here is my updated, working code:

const AWS = require("aws-sdk");
const sns = new AWS.SNS();

exports.handler = (event, context, callback) => {

const emailBody = 
`
Message

From: ${event.name}
Contact: ${event.contact}

Message: ${event.message}
`;

const snsMessageParams = {
    TopicArn: process.env.snsTopicArn,
    Message: emailBody
};

sns.publish(snsMessageParams, (err, data) => {
    if(err) {
        return err;
    } else {
        callback(null, JSON.stringify(data));
    }
});
};