AWS Lambda函数始终返回null(Node/Javascript)?

19

我有一个简单的Lambda函数,其目的是接收事件数据并将消息发送到SNS主题。

运行时为Node.js 8.10。

以下是我的完整Lambda代码:

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;
    }
  });
};
每次运行函数时,我总是得到一个空响应。没有错误返回,但我从SNS从来没有收到邮件消息,所以这里肯定有问题。我只是想不出到底是什么问题。
我能够成功地从SNS控制台和我的本地计算机上的Node SDK向我的SNS主题发布消息。这些都工作得很好。我已经检查了我的环境变量中snsTopicArn是否正确,通过直接从成功的本地代码和SNS控制台复制和粘贴它来完成。
我在Lambda函数上有一个执行角色,允许我发布到我的帐户中任何主题的SNS。我只是选择默认的“SNSPublish”选项来配置Lambda的角色以测试一切是否正常。但供参考,这是我的执行角色策略:
{
  "roleName": <MyRoleName>,
  "policies": [
    {
       "document": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": [
                "sns:Publish"
              ],
              "Resource": "arn:aws:sns:*:*:*"
            }
          ]
        }
    ...
}

这里出了什么问题?非常感谢任何帮助。


几件事情:1. 不确定资源部分的 ::* 会做什么。我建议先将其更改为 "Resource": "*",然后在确保它正常工作后再添加 SNS ARN。2. 将 Lambda 设置为写入 CloudWatch(LambdaFullAccess 或等效权限),然后在其中添加一些写入行,验证例如环境变量是否被正确读取等。我建议从这两个步骤开始。 - Zaxxon
@Zaxxon 感谢你的建议,不过我成功解决了问题,而不需要这样做。 - Z_z_Z
2个回答

30

好的,我解决了这个问题。

存在两个问题。第一个是我没有使用Lambda for Node隐式使用的"callback"参数。第二个问题是该函数默认是异步的,因此它期望稍后有一个"await"。我决定只是删除"async"并让它同步运行,因为这只是一个简单的函数,不需要异步。

这是我的更新后的、可工作的代码:

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));
    }
});
};

1
你可以使用promisify来避免回调函数风格,并使用async/await。 - Andy Gaskell
2
你还没有使用回调函数中的 err,正确的用法是:if(err) { callback(err, { statusCode: 500, body: Error: ${err}` }); } else { callback(null, JSON.stringify(data)); } - Matthew O'Riordan
2
本节文档:https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html - Arian Acosta

9
在我的情况下,我只是试图执行基本的 helloWorld 处理程序。
exports.helloWorld = (event, context) => {
    context.callbackWaitsForEmptyEventLoop = false;

    return {
        statusCode: 200,
        body: 'Hello World'
    }
}

我尝试使用上述功能,但响应为nullconsole.log正常工作。但在将async添加到函数后,出现了正确的响应。

exports.helloWorld = async (event, context) => {

1
谢谢。它对我有用。Console.log没问题,但返回“null”作为响应。现在得到了正确的JSON格式化双引号键值返回。 - Fakir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接