8
votes

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:

2

2 Answers

18
votes

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

3
votes

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