10

I have a simple Node.js 10.x Lambda function that works fine when tested on the Lambda function console:

exports.handler = async (event) => {
    var msg = 'connected';
    return { 
        statusCode: 200, 
        body: { msg: msg}
    };
};

I created a WebSocket API through their API Gateway console, that integrates to it through a LAMBDA_PROXY integration:

Websocket API on Amazon API Gateway web console

When I try to connect to it using wscat, I get an error:

wscat -c "wss://awesomeid1.execute-api.us-west-2.amazonaws.com/dev"
error: Unexpected server response: 502

How can I fix it?

Bonus question: how can we find the logs for the Websocket API connection errors?


Related links that didn't help me to fix it:

Ricardo
  • 3,696
  • 5
  • 36
  • 50

2 Answers2

24

I found the root cause on this answer. Basically, when using a Lambda Proxy Integration, the Lambda function response body value needs to be a string. We need to use JSON.stringify() or something similar:

exports.handler = async (event) => {
    var msg = 'connected';
    return { 
        statusCode: 200, 
        body: JSON.stringify({ msg: msg}) /*required on lambda proxy integration*/
    };
};

Digging into the docs, on the section Output Format of a Lambda Function for Proxy Integration:

In Lambda proxy integration, API Gateway requires the backend Lambda function to return output according to the following JSON format

    "isBase64Encoded": true|false,
    "statusCode": httpStatusCode,
    "headers": { "headerName": "headerValue", ... },
    "multiValueHeaders": { "headerName": ["headerValue", "headerValue2", ...], ... },
    "body": "..." } 

[...]

The output body is marshalled to the frontend as the method response payload [...]

If the function output is of a different format, API Gateway returns a 502 Bad Gateway error response.


Answer to the bonus question:

After adding a new IAM Role AmazonAPIGatewayPushToCloudWatchLogs, getting its ARN on its summary page, we can follow these steps:

Set up API Logging Using the API Gateway Console

And see that the log message on the server is more descriptive:

Execution failed due to configuration error: Malformed Lambda proxy response

Ricardo
  • 3,696
  • 5
  • 36
  • 50
  • I had the same issues and found the same solutions (even the bonus question :D) however, I can't get the $connect response client side? How do you retrieve your msg ? – Chris Oct 05 '19 at 19:50
  • Are you using [wscat](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-how-to-call-websocket-api-wscat.html) as a client tool? This link describes how to use it to connect to the WS API. – Ricardo Oct 07 '19 at 23:44
  • Yes I use wscat as well; Actually I have found my issue: I had IAM role missing the executeApi rights. Thanks anyway! – Chris Oct 08 '19 at 14:11
  • I got stung with this as well, as my $connect lambda returned `void` rather than `{statusCode:200}`, so my logic was running on the server side, but on the client, I would get a "cannot connect" error. Good find! – divillysausages Mar 31 '21 at 13:32
5

As you said above, you have to stringfy all messages of your websocket to send back to your clients.

Besides that, on websocket connect method you must not return, because you need to keep the connection opened to receive messages. You should calls the callback you received on connect method like this

callback(null, {
    statusCode: 200,
});
deHaar
  • 17,687
  • 10
  • 38
  • 51
Pablo Lopes
  • 133
  • 2
  • 9