1

I'm setting up the serverless framework to be able to push some messages to AWS SQS and everything is working up until the sqs.sendMessage logic and I can't seem to figure out what's going on. It gets to it and just dies, no error or anything.

I've tried a variety of configurations within serverless, and tried giving the SQS queue full rights to anyone for all SQS functions, none of that worked.

Serverless.yml

service: hook
provider:
  name: aws
  runtime: nodejs10.x
  stage: ${opt:stage, 'local'}
  region: ${opt:region, 'us-east-1'}
  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "sqs:SendMessage"
        - "sqs:GetQueueUrl"
      Resource:
        Fn::GetAtt: 
          - HookQueue
          - Arn 
    - Effect: "Allow"
      Action:
        - "sqs:ListQueues"
      Resource:
        Fn::GetAtt: 
          - HookQueue
          - Arn
functions:
  hookListener:
    handler: handler.hook
    events:
      - http:
          path: hook
          method: post
    environment:
      SQS_URL: 
        Ref: HookQueue

resources:
  Resources:
    HookQueue:
      Type: "AWS::SQS::Queue"
      Properties:
        QueueName: "HookQueue-${opt:stage, 'local'}"

Handler.js

'use strict';

var AWS = require('aws-sdk');
var sqs = new AWS.SQS({
    region: 'us-east-1'
});

module.exports.hook = (event, context, callback) => {
  console.log(event);

  var eBody = JSON.parse(event.body);

  var queueUrl = process.env.SQS_URL;
  console.log('SQS url is: ' + queueUrl);


  var realmID = 1234
  console.log('attempting to store: ' + realmID + ' body: ' + event.body);
  var params = {
    MessageBody: JSON.stringify({  realmID: realmID,
                    entities: event.body}),
    QueueUrl: queueUrl
  };
  console.log('got here');

  //Send message to SQS queue
  sqs.sendMessage(params, function(err, data) {
    if (err) {
        console.log('error:', "failed to send message" + err);
        callback(null, {statusCode: 500, body: 'Internal Service Error'});
    } else {
        console.log('data:' + data.MessageId);
        console.log('Sent to ' + queueUrl);
        console.log(data.MessageId);
    }
    console.log('after the send logic');
  });

  callback(null, {statusCode: 200, body: 'Success'});

};


Looking for any suggestions, thanks!

8
  • Lambda functions can't "just die" with no error. They either finish executing without an error, or they throw an error. What do the cloudwatch logs show for one of these invocations? Commented Sep 9, 2019 at 7:30
  • I don't know how to explain what I'm seeing though. In my code I have a console.log statement right before the sqs.sendmessage, and it makes that logging statement. Then it hits the sendmessage function, and I don't see any console writes after that. I would expect to either see an error or a log of the data. Based on there being nothing in my SQS queue I would expect to see some sort of error message, but I don't see any of that. It goes straight to "END Request ID:" Commented Sep 9, 2019 at 12:22
  • Okay, so your Lambda function is completing successfully. You stripped out the actual handler function declararion from your question, and that's an important piece of this puzzle. I'm guessing it's an async function, and if so, then that's the problem -- if you want that, then the SQS invocation needs to use promises and await, not callbacks; otherwise remove async from the handler declaration. Commented Sep 9, 2019 at 13:22
  • I am using callbacks, not async. I edited the original post, function declaration is: module.exports.hook = (event, context, callback) => { Commented Sep 9, 2019 at 13:40
  • Thanks for the update. There's another point that confuses me... handler: handler.hook != quickhook. Commented Sep 9, 2019 at 13:45

2 Answers 2

2

Was a result of me brain farting around node being asynchronous and hitting the callback before it finished processing.

Sign up to request clarification or add additional context in comments.

Comments

1

You should return a response in your lambda to see the result:

var queueUrl = process.env.SQS_URL;
var realmID = 1234
var params = {
        MessageBody: JSON.stringify({  realmID: realmID,
                        entities: event.body}),
        QueueUrl: queueUrl
      };

//Send message to SQS queue
sqs.sendMessage(params, function(err, data) {
  if (err) {
    console.log('error:', "failed to send message" + err);
    callback(null, {statusCode: 500, body: 'Internal Service Error'});
  } else {
    callback(null, {statusCode: 200, body: JSON.stringify(data)});
    console.log('data:' + data.MessageId);
    console.log('Sent to ' + queueUrl);
    console.log(data.MessageId);
  }
  console.log('after the send logic');
});

Also you don't need a Lambda to to publish a message to an SQS Queue. You can set up an API Gateway service proxy to directly map a request to a Queue.

This plugin makes it very easy (I'm one of the collaborators) and also saves you the cost of the Lambda invocations.

4 Comments

My method will do more than just a simple write to an SQS queue, there will be other stuff happening, I just can't get past the writing to the SQS piece yet. However I do think I'll be able to make use of that plugin in the future. Also, I do have a return statement after the else, I just didn't include it in my post.
Do you mind including the full code of your handler including the return statement? You could also wrap the entire call to sqs.sendMessage in try catch and log the error of calling sqs.sendMessage
Updated. Also, I tried wrapping it all in a try catch and it didn't catch anything, which I thought was bizarre. I'm going to wipe out my s3 bucket and everything and make sure my serverless framework is deploying properly.
You're calling the callback in the wrong place, it should be inside the sendMessage block as seen in my initial answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.