1

I'm running a AWS Lambda function in Node.js 14, bound to a REST API in API Gateway with LAMBDA_PROXY.

Consider this simplified Pseudo Code for index.js:

exports.handler = async function (event, context) {
    if (event.body.myParam === '1') {
        // Works!
        return {
            statusCode: 302,
            headers: {
                Location: 'https://iam.aredire.ct'
            }
        };
    } else if (event.body.myParam === '2') {
        // Works! 403 - {"message":"You are not allowed to do that!"}
        return {
            statusCode: 403,
            body: JSON.stringify({
                message: 'You are not allowed to do that!'
            })
        };
    } else if (event.body.myParam === '3') {
        const jwt = require('jsonwebtoken');
        const token = 'ey...';
        const pubKey = '-----BEGIN PUBLIC KEY----- ...';

        // Some promise
        return new Promise(function (resolve, reject) {
            // Some async call
            jwt.verify(token, pubKey, function (err, decoded) {
                if (err) {
                    // gets logged
                    console.log(err);

                    // 502 - {"message": "Internal server error"}
                    return reject({
                        statusCode: 403,
                        body: JSON.stringify({
                            message: 'No valid token'
                        })
                    });

                    // 502 - {"message": "Internal server error"}
                    return reject(JSON.stringify({
                        statusCode: 403,
                        body: {
                            message: 'No valid token'
                        }
                    }));
                }
                // Works! 200 - {"message":"Works!"}
                resolve({
                    statusCode: 200,
                    body: JSON.stringify({
                        message: 'Works!'
                    })
                });
            });
        });
    }
}

Please see the comments in the code snippets. Do you have any idea why resolve() and return work as expected but reject() always returns 502 - {"message": "Internal server error"}? I want that the requester actually gets a 403 - {"message": "No valid token"}?

I read about JSON.stringifying the whole error object, but that does not help.

Cloudwatch raises this error:

ERROR   Invoke Error    
{
    "errorType": "Error",
    "errorMessage": "{\"statusCode\":403,\"body\":{\"message\":\"No valid token\"}}",
    "stack": [
        ...
    ]
}

1 Answer 1

2

See Error Handling in Other Services:

API Gateway treats all invocation and function errors as internal errors. If the Lambda API rejects the invocation request, API Gateway returns a 500 error code. If the function runs but returns an error, or returns a response in the wrong format, API Gateway returns a 502 error code. To customize the error response, you must catch errors in your code and format a response in the required format.

You should resolve the promise, rather than reject it, to indicate to API Gateway that it completed normally, and include the relevant 4xx statusCode and body to indicate to your client (not API Gateway) that it represents an application-level failure.

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

1 Comment

I must have overseen this paragraph, thank you! Makes sense to catch application-level errors by myself and not to pass them to API Gateway as errors.

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.