Ошибка AWS lambda api-шлюза "Отказ от ложного ответа Lambda"

Я пытаюсь создать приветственный пример мира с помощью лямбда AWS и обслуживать его через api gateway. Я нажал кнопку "Создать функцию лямбда", которая настроила api gatway и выбрала опцию "Пустая функция". Я добавил функцию лямбда, найденную в Руководство по началу работы с AWS:

exports.handler = function(event, context, callback) {
  callback(null, {"Hello":"World"});  // SUCCESS with message
};

Проблема в том, что когда я делаю запрос GET, он возвращает ответ 502 { "message": "Internal server error" }. И в журналах говорится: "Выполнение завершилось неудачно из-за ошибки конфигурации:" Отказ от ответа на Lambda ".

Ответ 1

Обычно, когда вы видите Malformed Lambda proxy response, это означает, что ваш ответ от вашей функции Lambda не соответствует формату, который ожидает API-интерфейс API, например

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

Если вы не используете интеграцию с Lambda proxy, вы можете войти в консоль API Gateway и снять отметку с флажка интеграции с Lambda proxy.

Кроме того, если вы видите прерывистый Malformed Lambda proxy response, это может означать, что запрос к вашей лямбда-функции был дросселирован Lambda, и вам нужно запросить увеличение лимита выполнения на Lambda.

Ответ 2

Если лямбда используется как прокси-сервер, тогда формат ответа должен быть

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

Примечание: тело должно быть сжато

Ответ 3

Да, поэтому я думаю, что это потому, что вы на самом деле не возвращаете правильный ответ HTTP, поэтому вы получаете ошибку.

лично я использую набор таких функций:

    module.exports = {
        success: (result) => {
            return {
                statusCode: 200,
                headers: {
                    "Access-Control-Allow-Origin" : "*", // Required for CORS support to work
                    "Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS
                },
                body: JSON.stringify(result),
            }
        },
        internalServerError: (msg) => {
            return {
                statusCode: 500,
                headers: {
                    "Access-Control-Allow-Origin" : "*", // Required for CORS support to work
                    "Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS
                },
                body: JSON.stringify({
                    statusCode: 500,
                    error: 'Internal Server Error',
                    internalError: JSON.stringify(msg),
                }),
            }
        }
} // add more responses here.

Затем вы просто выполните:

var responder = require('responder')

// some code

callback(null, responder.success({ message: 'hello world'}))

Ответ 4

Из документов AWS

В лямбда-функции в Node.js, чтобы вернуть успешный ответ, вызовите обратный вызов (null, {"statusCode": 200, "body": "results"}). Бросить исключение, обратный вызов (новая ошибка ("внутренняя ошибка сервера")). Для ошибка на стороне клиента, например, отсутствует обязательный параметр, вы можете вызвать обратный вызов (null, {"statusCode": 400, "body": "отсутствуют параметры... "}) чтобы вернуть ошибку без исключения.

Ответ 5

Очень особый случай, если вы передаете заголовки напрямую, есть вероятность, что у вас есть этот заголовок:

"set-cookie": [ "........" ]

Но Amazon нужно это:

"set-cookie": "[ \\"........\\" ]"

Ответ 6

Для всех, кто борется, когда ответ кажется действительным. Это не работает:

callback(null,JSON.stringify( {
  isBase64Encoded: false,
  statusCode: 200,
  headers: { 'headerName': 'headerValue' },
  body: 'hello world'
})

но это делает:

callback(null,JSON.stringify( {
  'isBase64Encoded': false,
  'statusCode': 200,
  'headers': { 'headerName': 'headerValue' },
  'body': 'hello world'
})

Кроме того, похоже, что в объекте ответа не должно быть никаких дополнительных ключей.

Ответ 7

Если вы используете Go с https://github.com/aws/aws-lambda-go, вы должны использовать events.APIGatewayProxyResponse.

func hello(ctx context.Context, event ImageEditorEvent) (events.APIGatewayProxyResponse, error) {
    return events.APIGatewayProxyResponse{
        IsBase64Encoded: false,
        StatusCode:      200,
        Headers:         headers,
        Body:            body,
    }, nil
}

Ответ 8

У меня была эта ошибка, потому что я случайно удалил переменную ServerlessExpressLambdaFunctionName из ресурса CloudFormation AWS:: Serverless:: Api. Контекст здесь https://github.com/awslabs/aws-serverless-express "Запуск приложений без сервера и API REST с использованием существующей инфраструктуры приложений Node.js, поверх AWS Lambda и шлюз API Amazon"

Ответ 9

Я испробовал все приведенные выше предложения, но они не работают, пока значение body не равно String

return {
    statusCode: 200,
    headers: {
        "Content-Type": "application/json",
        "Access-Control-Allow-Origin": "*"
    },
    body: JSON.stringify({
        success: true
    }),
    isBase64Encoded: false
};

Ответ 10

В случае, если вышеописанное не работает ни для кого, я столкнулся с этой ошибкой, несмотря на правильную настройку переменной ответа.

Я выполнял вызов базы данных RDS в моей функции. Оказалось, что причиной проблемы были правила группы безопасности (входящие) в этой базе данных.

Возможно, вы захотите ограничить IP-адреса, которые могут получить доступ к API, но если вы хотите, чтобы он работал быстро/грязно, чтобы проверить, исправит ли это изменение, вы можете настроить его на прием всех подобных параметров (вы также можете установить диапазон портов, чтобы принимать все порты тоже, но я не делал этого в этом примере):

enter image description here

Ответ 11

Для Python3:

import json

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'headers': {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': '*'
        },
        'body': json.dumps({
            'success': True
        }),
        "isBase64Encoded": False
    }

Обратите внимание, что body необязательно устанавливать, он может быть пустым:

        'body': ''

Ответ 12

Распространенной причиной ошибки "Неправильный отклик лямбда-прокси" является headers, которая не является {String: String, ...} парами ключ/значение.

Поскольку заголовки set-cookie могут появляться и появляются в нескольких местах, они представлены в http.request.callback.response как ключ set-cookie, имеющий Array из Strings значение вместо одного String. Хотя это работает для разработчиков, AWS API-шлюз не понимает этого и выдает "неправильный ответ лямбда-прокси" ошибка.

Мое решение - сделать что-то вроде этого:

function createHeaders(headers) {
  const singleValueHeaders = {}
  const multiValueHeaders = {}
  Object.entries(headers).forEach(([key, value]) => {
    const targetHeaders = Array.isArray(value) ? multiValueHeaders : singleValueHeaders
    Object.assign(targetHeaders, { [key]: value })
  })

  return {
    headers: singleValueHeaders,
    multiValueHeaders,
  }
}

var output = {
  ...{
    "statusCode": response.statusCode,
    "body": responseString
  },
  ...createHeaders(response.headers)
}

Обратите внимание, что ... выше не означает Yada Yada Yada. Это оператор распространения ES6.