Function is succeeding but getting {“message”: “Internal server error”} on API Gateway responses

Function is succeeding but getting {“message”: “Internal server error”} on API Gateway responses with serverless framework 1.17

Need some help regarding how to debug this further. I have read the other posts that are similar in the forum but haven’t been able to resolve the issue yet. I using serverless framework 1.17.0. When I send a http PUT to the API gateway endpoint I am receiving the following:

response header:

content-length →36
content-type →application/json
date →Sat, 12 Aug 2017 22:21:15 GMT
status →502
via →1.1 12d553da488f4b888f83cd96bab2823b.cloudfront.net (CloudFront)
x-amz-cf-id →w6nuC215apoGNNgD3VfErtxiGsKBUVUJ0meGBI9Okj5nzf2f3qvnxQ==
x-amzn-requestid →8d01894b-7fac-11e7-a18a-b1a7078f6dae
x-cache →Error from cloudfront 

response body:

{
    "message": "Internal server error"
}

This is the response as contained in the sls logs:

{ statusCode: 200,
  headers: { 'Access-Control-Allow-Origin': '*',
             'Access-Control-Allow-Credentials': true,
             'Content-Type': 'application/json' },
  body: '{"message":"Test message"}' }

This is my function definition in serverless.yml

  verifyPhone:
    handler: backend/phone.verifyPhone
    events:
      - http:
          cors: true
          path: /verifyPhone
          method: put

I have read the serverless document regarding the setup of API Gateway events and tried to setup the statusCode, headers and body as shown in that document. What am I missing?

1 Like

Can you include your handler code? At least he part(s) that determine the response object.

Usually, I get this error when I forget to JSON.stringify() the body payload for the lambda-proxy integration but it looks like you’re doing that, so it must be something else in the returned object that’s doing it. You can tell it’s an issue with the payload, because the error is happening when API Gateway is attempting to “render” the response - everything is fine in your code, but getting 500s on the client.

Appreciate the response! Here is the handler code:

phoneLookup(contact.phone_number)
        .then(function (result) {
          console.log("number: ",result);
          var msg = "Test message"
          var response = {
              statusCode: 200,
              headers: { "Access-Control-Allow-Origin": "*",
                         "Access-Control-Allow-*" : true, 
                         "Content-Type": "application/json"},
              body: JSON.stringify({ "message": msg })
          } 
          console.log("Response: ",response)
          return response      
        })
        .catch(function (error) {
          console.log("Error: ",error.message)
        });

In the code you’ve shared you’ve got a header “Access-Control-Allow-*” that you didn’t have in your original snippet. Is that (the wildcard in the header name) allowed? I haven’t seen it before.

I’ve updated the handler code to:

      var response = {
          statusCode: 200,
          headers: { "Access-Control-Allow-Origin": "*",
                     "Access-Control-Allow-Credentials" : true, 
                     "Content-Type": "application/json"},
          body: JSON.stringify({ "message": msg })
      }

Same result. Are there any other headers I need to specify?

I must be missing something in my configuration. I have another simple function that queries data from a dynamoDB table. The query is successful and I can see the results in the logs but the client still gets the {“message”: “Internal server error”}

okay, I have to be missing something obvious. I simplified even further using a basic ‘Hello World’ example. Testing using sls invoke -f hello works as expected. However when I use postman to execute a simple GET request the client still gets the status 502 Bad Gateway with {“message”: “Internal server error”} I have included below both the function definition as well as the handler.

serverless.yml function definition

hello:
handler: backend/test.hello
events:
- http:
cors: true
path: /hello
method: get

handler

‘use strict’;

module.exports.hello = function(event, context, callback) {

console.log(event); // Contains incoming request data (e.g., query params, headers and more)
console.log('Testing...'); // Contains incoming request data (e.g., query params, headers and more)

const response = {
  statusCode: 200,
  headers: {
    "headers": { "Access-Control-Allow-Origin": "*", "Content-Type": "application/json"},
  },
  body: JSON.stringify({ "message": "Hello World!" })
};

callback(null, response);

};

@rlr0329: For the most recent example, you’ve got a “headers” key inside your “headers” key :slight_smile: When I removed that, I was able to get it to work:

// handler.js

'use strict';

module.exports.hello = function(event, context, callback) {

  console.log(event); // Contains incoming request data (e.g., query params, headers and more)
  console.log('Testing...'); // Contains incoming request data (e.g., query params, headers and more)

  const response = {
    statusCode: 200,
    headers: {
        "Access-Control-Allow-Origin": "*",
        "Content-Type": "application/json"
    },
    body: JSON.stringify({ "message": "Hello World!" })
  };

  callback(null, response);
};

Does that solve your problem with the simple example? And anything similar in your other code that could be causing issues?

2 Likes

Thank you alexdebrie1! That did solve the problem with the simple example. Can’t believe I missed that. :frowning:

Found the problem with my other example–it was an issue with the callback. The module definition was:

module.exports.getPrjList = (event, context, callback) => {

I was simply doing a ‘return response’ instead of callback(null, response);

I am new to nodeJS and still trying to wrap my head around callbacks. Anyways, thanks again for your help!!