Home > Blockchain >  AWS Lambda sends SQS message twice with one call
AWS Lambda sends SQS message twice with one call

Time:10-12

I need to only deliver a message to a standard (not FIFO, but is not related to the question) SQS queue, once with one call.

However, the code below is sending 2 messages with 1 call.

const AWS = require('aws-sdk')
AWS.config.update({region: process.env.AWS_REGION})
const sqs = new AWS.SQS({apiVersion: '2012-11-05'});

async function sendToSQSEvent(body,attributes=null){
    var m_body 
    if (attributes != null)
    {
            m_body = {
                body : body,
                attributes : attributes
                };
    }
    else{
        m_body = body;
    }
    m_body = JSON.stringify(m_body);
            
 var params = {
    //  DelaySeconds: 0,   <-- i try but only delay reception 
      MessageAttributes: {
        "Title": {
          DataType: "String",
          StringValue: "TIME_OUT"
        },
        "Author": {
          DataType: "String",
          StringValue: "LAMBDA_IN"
        },
      },
      MessageBody: m_body,
      QueueUrl: "https://my_url/sqs"
    };
    console.log('_________CALL_______________');
    var r = await sqs.sendMessage(params, function(err, data) {
      if (err) {
        console.log("Error", err);
      } else {
        console.log("Success", data.MessageId ,data);
      }
    }).promise(console.log("_________in promise___________"));
   console.log("___end")
}

exports.handler = async (event, context) => {
     await sendToSQSEvent(event)
};

Console output is:

START RequestId: RequestId Version: $LATEST
2021-10-11T06:23:52.992Z    RequestId   INFO    _________CALL_______________
2021-10-11T06:23:53.425Z    RequestId   INFO    _________in promise___________
2021-10-11T06:23:53.728Z    RequestId   INFO    Success ********-****-****-****-*********b4f {
  ResponseMetadata: { RequestId: '********-****-****-****-*********89d' },
  MD5OfMessageBody: '********************************8f',
  MD5OfMessageAttributes: '***********************1b0',
  MessageId: '********-****-****-****-*********b4f'
}
2021-10-11T06:23:53.786Z    RequestId   INFO    ___end
2021-10-11T06:23:53.807Z    RequestId   INFO    Success ********-****-****-****-*********665 {
  ResponseMetadata: { RequestId: '********-****-****-****-********835' },
  MD5OfMessageBody: '***********************28f',
  MD5OfMessageAttributes: '***********************1b0',
  MessageId: '********-****-****-****-*********665'
}
END RequestId: RequestId

What is the issue?

CodePudding user response:

It's sending a message twice as you're mixing synchronous callbacks (function(err, data)) with asynchronous promises (await, async function sendToSQSEvent(...)).

You can see this as CloudWatch is logging 2 sqs.sendMessage(...) responses.

I would recommend sticking with the latter.


This should be your SQS sendMessage logic, which returns a promise object for your handler.

return sqs.sendMessage(params).promise();

You can then check the response in your handler:

exports.handler = async (event, context) => {
    try {
        var data = await sendToSQSEvent(event)
        console.log("Success", data.MessageId ,data);
    }
    catch (err){
        console.log("Error", err);
    }
};

This should be the final working result:

const AWS = require('aws-sdk')
AWS.config.update({
    region: process.env.AWS_REGION
})
const sqs = new AWS.SQS({
    apiVersion: '2012-11-05'
});

async function sendToSQSEvent(body, attributes = null) {
    var m_body
    if (attributes != null) {
        m_body = {
            body: body,
            attributes: attributes
        };
    } else {
        m_body = body;
    }
    m_body = JSON.stringify(m_body);

    var params = {
        MessageAttributes: {
            "Title": {
                DataType: "String",
                StringValue: "TIME_OUT"
            },
            "Author": {
                DataType: "String",
                StringValue: "LAMBDA_IN"
            },
        },
        MessageBody: m_body,
        QueueUrl: "https://my_url/sqs"
    };

    return sqs.sendMessage(params).promise();
}

exports.handler = async (event, context) => {
    try {
        var data = await sendToSQSEvent(event)
        console.log("Success", data.MessageId ,data);
    }
    catch (err){
        console.log("Error", err);
    }
};
  • Related