使用Lambda(Node.js)发布SNS消息导致超时错误

5

我使用了一个非常简单的代码,稍微修改了AWS提供的示例:

    exports.handler = async (event) => {
        // Load the AWS SDK for Node.js
        var AWS = require('aws-sdk');
        // Set region
        AWS.config.update({region: 'ap-southeast-2'});
    
        // Create publish parameters
        var params = {
            Message: 'This is a sample message',
            Subject: 'Test SNS From Lambda',
            TopicArn: 'arn:aws:sns:ap-southeast-2:577913011449:TestTopic'
        };
    
        // Create promise and SNS service object
        var publishTextPromise = new AWS.SNS().publish(params).promise();
    
        let response = {
            statusCode: 200,
            body: JSON.stringify('Hello from Lambda!'),
        };
    
        // Handle promise's fulfilled/rejected states
        publishTextPromise.then(
            function(data) {
                console.log("Message ${params.Message} send sent to the topic ${params.TopicArn}");
                console.log("MessageID is " + data.MessageId);
                response.result = 'Success';
            }).catch(
                function(err) {
                console.error(err, err.stack);
                response.result = 'Error';
            });
    
        
        return response;
    };

当测试该服务时,我遇到了超时错误。限制时间为3秒。

由于这是一个非常简单的过程,我认为执行它不应该超过3秒。

我已经检查了我的IAM设置,并授予了我的个人资料(管理员资料)对SNS服务具有完全访问权限。但错误仍然存在。我想知道这里出了什么问题,以及我应该如何解决?

1个回答

11

我不确定为什么会出现超时,但是你的代码并不按照你期望的方式工作。

请注意你在.then()代码外部返回了响应,这意味着你的代码将在.then()代码甚至运行之前就会返回(Promise是异步的)。

由于你已经使用Node 8,使用async/await比使用旧的.then().catch()方法更好。

我对你的代码进行了一些重构,并且它可以很好地工作。我保留了原始参数以方便你使用。看看代码如何变得更容易阅读和调试。

'use strict';

// Load the AWS SDK for Node.js
const AWS = require('aws-sdk');
// Set region
AWS.config.update({region: 'ap-southeast-2'});

const sns = new AWS.SNS()

module.exports.handler = async (event) => {

  const params = {
    Message: 'This is a sample message',
    Subject: 'Test SNS From Lambda',
    TopicArn: 'arn:aws:sns:ap-southeast-2:577913011449:TestTopic'
  };

  let response = {
    statusCode: 200,
    body: JSON.stringify('Hello from Lambda!'),
  };
  try {
    const data = await sns.publish(params).promise();
    response.messageId = data.MessageId,
    response.result = 'Success'
  } catch (e) {
    console.log(e.stack)
    response.result = 'Error'
  }
  return response

};

如果由于任何原因您不想使用async/await,那么您需要将函数的返回移至.then()代码内,并且在promise被调用后立即返回,代码如下:
'use strict';

// Load the AWS SDK for Node.js
var AWS = require('aws-sdk');
// Set region
AWS.config.update({region: 'ap-southeast-2''});

// Create publish parameters
var params = {
    Message: 'This is a sample message',
    Subject: 'Test SNS From Lambda',
    TopicArn: 'arn:aws:sns:ap-southeast-2:577913011449:TestTopic'
};

module.exports.handler = async (event) => {

  // Create promise and SNS service object
  var publishTextPromise = new AWS.SNS().publish(params).promise();

  let response = {
      statusCode: 200,
      body: JSON.stringify('Hello from Lambda!'),
  };

  // Handle promise's fulfilled/rejected states
  return publishTextPromise.then(
      function(data) {
          console.log("Message ${params.Message} send sent to the topic ${params.TopicArn}");
          console.log("MessageID is " + data.MessageId);
          response.result = 'Success';
          return response;
      }).catch(
          function(err) {
          console.error(err, err.stack);
          response.result = 'Error';
          return response
      });

};

我强烈建议你采用第一种方法。

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