Публикация сообщения SNS от лямбды (узла js) приводит к ошибке тайм-аута - PullRequest
1 голос
/ 08 марта 2019

Я использовал очень простой код, слегка модифицированный из предоставленного 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 Ответ

1 голос
/ 08 марта 2019

Я не уверен, почему вы получаете тайм-аут, но ваш код не должен работать так, как вы ожидаете.

Убедитесь, что вы возвращаете свой ответ за пределы кода .then(), то есть ваш код будет возвращаться до того, как ваш код .then() будет запущен (обещания асинхронны).

Поскольку вы уже используете 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 (), а также возврат сразу после вызова обещания, например, так: :

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

};

Я настоятельно рекомендую вам использовать подход № 1.

...