Как сгенерировать код ошибки HTTP с AWS Lambda с помощью Lambda Proxy? - PullRequest
1 голос
/ 14 февраля 2020

Я создал AWS лямбда-функцию, используя Python 3.8 с Лямбда-прокси Триггер API-шлюза: API Gateway

Это действительно возможно возвращать пользовательские коды ошибок HTTP:

def lambda_handler(event, context):
    return {
        'statusCode': 400,
        'body': json.dumps('This is a bad request!')
    }

Однако некоторые онлайн-примеры (например, 1 , 2 ) просто вызывают исключение, чтобы вернуть ошибку с пользовательским сообщением , Если на обработчик выдано исключение, как показано ниже, сервер возвращает 502, поскольку ответ не в ожидаемом формате для интеграции прокси :

def lambda_handler(event, context):
    raise Exception('This is an exception!')

Я думаю, что примеры основаны на некоторые шаблоны ответов Integration и не используют Proxy Integration. Можно ли добиться того же с помощью Lambda Proxy? Я бы хотел избежать глобального перехвата исключений в обработчике Lambda для создания пользовательских ответов об ошибках.

Ответы [ 2 ]

1 голос
/ 23 февраля 2020

DurandA - я считаю, что вы абсолютно правы: упрощенный подход интеграции Lambda Proxy основан на том, что вы перехватываете исключения и возвращаете стандартизированный формат:

def lambda_handler(event, context):
    return {
        'statusCode': 400,
        'body': json.dumps('This is a bad request!')
    }

Упрощенная функция интеграции Lambda Proxy была объявлена ​​в Сообщение в блоге за сентябрь 2016 года , но один из приведенных вами примеров был опубликован ранее, в сообщении в блоге за июнь 2016 года , когда более сложный метод Integration Response был единственным способом. Возможно, вы наткнулись на устаревший пример.

Вы также разместили ссылку на документацию по продукту для обработки ошибок в верхней части раздела, посвященного функции интеграции прокси-серверов Lambda. говорит:

С интеграцией прокси-сервера Lambda Lambda должна возвращать вывод следующего формата:

{
  "isBase64Encoded" : "boolean",
  "statusCode": "number",
  "headers": { ... },
  "body": "JSON string"
}

Вот рабочий пример, который возвращает HTTP 400 с сообщением "Это исключение!" использование интеграции лямбда-прокси.

import json

def exception_handler(e):
    # exception to status code mapping goes here...
    status_code = 400
    return {
        'statusCode': status_code,
        'body': json.dumps(str(e))
    }

def lambda_handler(event, context):
    try:
        raise Exception('This is an exception!')
        return {
            'statusCode': 200,
            'body': json.dumps('This is a good request!')
        }
    except Exception as e:
        return exception_handler(e)

Вывод из вышеизложенного:

$ http https://**********.execute-api.us-east-2.amazonaws.com/test
HTTP/1.1 400 Bad Request
Connection: keep-alive
Content-Length: 23
Content-Type: application/json
Date: Sun, 23 Feb 2020 05:06:59 GMT
X-Amzn-Trace-Id: Root=1-********-************************;Sampled=0
x-amz-apigw-id: ****************
x-amzn-RequestId: ********-****-****-****-************

"This is an exception!"

Я понимаю ваше разочарование тем, что вы не хотите создавать пользовательский обработчик исключений. К счастью, вам нужно создать только один обработчик, упаковывающий вашу функцию lambda_handler. Желаю вам всего наилучшего!

1 голос
/ 18 февраля 2020

Насколько я знаю, использование языка, встроенного в Exceptions, не будет работать, потому что API Gateway ожидает точный формат ответа, который является JSON. Что вы можете сделать, так это вызвать исключение, чтобы оно могло быть зарегистрировано в CloudWatch, но затем обернуть его внутри объекта JSON, чтобы вы также могли вернуть его клиенту, если это необходимо. Я действительно думаю, что это должно быть возможно «из коробки», поскольку с помощью служб ECS вы можете сделать это (я использую некоторые службы в. NET Core и, когда возникает исключение, я получаю соответствующий код состояния в качестве ответа, не выполняя дополнительную работу )

...