【问题标题】:How to throw HTTP error code with AWS Lambda using Lambda Proxy?如何使用 Lambda 代理向 AWS Lambda 抛出 HTTP 错误代码?
【发布时间】:2020-02-14 11:11:38
【问题描述】:

我使用 Python 3.8 和 Lambda 代理 API Gateway 触发器创建了一个 AWS Lambda 函数:

确实可以返回自定义HTTP错误码:

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

但是,一些在线示例(例如12)只是简单地引发异常以返回带有自定义消息的错误。如果在下面的处理程序上抛出异常,服务器将返回 502,因为响应为 not in the expected format for Proxy Integration

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

我认为这些示例依赖于一些集成响应模板并且不使用代理集成。是否可以使用 Lambda 代理实现相同的目标?我想避免在 Lambda 处理程序中全局捕获异常来构建自定义错误响应。

【问题讨论】:

  • 引发异常将不起作用,因为它们不符合 API-Lambda 代理集成所需的响应格式。您可以构建自定义响应并将其作为您共享的第一个示例返回。

标签: python amazon-web-services aws-lambda aws-api-gateway


【解决方案1】:

DurandA - 我相信您是绝对正确的:简化的 Lambda 代理集成方法依赖于您捕获异常并返回标准化格式:

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

简化的 Lambda 代理集成功能已在 September 2016 blog post 中公布,但您引用的其中一个示例已在之前的 June 2016 blog post 中发布,当时更复杂的集成响应方法是唯一的方法。也许你偶然发现了一个过时的例子。

您还在 Lambda 代理集成功能部分的顶部发布了指向 product documentation for error handling 的链接,上面写着:

使用 Lambda 代理集成,Lambda 需要返回一个 以下格式的输出:

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

这是一个返回 HTTP 400 并带有消息“这是异常!”的工作示例。使用 Lambda 代理集成。

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 函数的处理程序。祝你一切顺利!

【讨论】:

  • 非常感谢您!从 AWS Docs 获得处理异常的正确方法非常困难
  • 看起来棒极了。我不确定,如果这种方法目前被认为是一种好的做法?困扰我的是,总是提出一般例外,而不是具体例外。
【解决方案2】:

据我所知,使用Exceptions 中内置的语言是行不通的,因为 API 网关需要一个精确的响应格式,即 JSON。您可以做的仍然是引发异常,以便可以将其记录到 CloudWatch 中,然后将其包装在 JSON 对象中,以便您也可以在需要时将其返回给客户端。我真的认为这应该是开箱即用的,因为使用 ECS 服务你可以做到这一点(我在 .NET Core 中使用一些服务,当发生异常时,我会得到适当的状态代码作为响应,而无需做额外的工作)

【讨论】:

    【解决方案3】:

    对于简单的情况,Chuck T. 的通用方法可能是可以的。但是,如果您有复杂的工作流程,包含多个协调的 Lambda 函数和 AWS 状态机,您可以使用here 中描述的更灵活的策略。

    1. 在您的函数中,创建许多简单的自定义异常类,如下所示:class SecretAccessFailedException(Exception): pass.
    2. 根据需要引发这些自定义异常。
    3. 在您的状态机中捕获它们并灵活处理。

    【讨论】:

      猜你喜欢
      • 2021-09-22
      • 2017-05-23
      • 2021-09-19
      • 1970-01-01
      • 2017-09-28
      • 1970-01-01
      • 2017-10-04
      相关资源
      最近更新 更多