【问题标题】:AWS API Gateway Lambda failed with status 200AWS API Gateway Lambda 失败,状态为 200
【发布时间】:2020-03-18 19:10:04
【问题描述】:

我正在编写一个微服务,我的 lambda 处理程序在请求的主体中采用 JSON 并构建一个 Jinja2 模板。我的 Lambda 函数工作正常并返回状态代码 200,但是当我通过 API 网关调用该函数时,我收到 502 响应。

def lambda_handler(event, context):
    try:
        file_object = s3.get_object(Bucket= 'bucket_name', Key='object_name')
        file_content = file_object["Body"].read().decode('utf-8')
        template = Template(file_content)
        rendered_template = template.render(resume = request_body)
        # Do some logic to place render in s3 and get path
        response = {
            'statusCode': 200,
            'header': {'Content-Type': 'application/json'},
            'body': 'path to file'
        }
        return response
    except Exception as e:
        print(e)
        raise e

我使用的请求正文类似于:

{
  "username": "john-doe",
  "location": "US",
  .
  .
  .
}

我收到的响应错误是:

{
  "errorMessage": "'str object' has no attribute 'lastName'",
  "errorType": "UndefinedError",
  "stackTrace": [
    "  File \"/var/task/resume_service.py\", line 39, in lambda_handler\n    raise e\n",
    "  File \"/var/task/resume_service.py\", line 25, in lambda_handler\n    generate = template.render(resume=request_body)\n",
    "  File \"/var/task/jinja2/asyncsupport.py\", line 76, in render\n    return original_render(self, *args, **kwargs)\n",
    "  File \"/var/task/jinja2/environment.py\", line 1008, in render\n    return self.environment.handle_exception(exc_info, True)\n",
    "  File \"/var/task/jinja2/environment.py\", line 780, in handle_exception\n    reraise(exc_type, exc_value, tb)\n",
    "  File \"/var/task/jinja2/_compat.py\", line 37, in reraise\n    raise value.with_traceback(tb)\n",
    "  File \"<template>\", line 28, in top-level template code\n",
    "  File \"/var/task/jinja2/environment.py\", line 411, in getitem\n    return obj[argument]\n"
  ]
}

为什么Lambda函数自己调用成功,通过API网关调用失败?

【问题讨论】:

  • 我错过了什么吗?姓氏甚至不在函数内
  • 你能添加你的 api getway image 你是如何创建它的吗,好像你没有在网关中添加参数

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


【解决方案1】:

问题恰好出在 Jinja2 上。 Jinja2 有几个创建函数来渲染带有给定参数的模板。

render([context]): "此方法接受与dict构造函数相同的参数"

generate([context]): "对于非常大的模板,它不会一次渲染整个模板,而是一个接一个地评估每个语句。

由于我的模板的大小,它无法通过更改来渲染()整个模板

rendered_template = Template.render(resume = request_body) 到: rendered_template = Template.generate(resume = request_body)

问题已解决。

【讨论】:

    【解决方案2】:

    在将 API Gateway 与 Lambda 代理集成一起使用时,API Gateway 期望从 Lambda 返回的数据采用here 列出的特定格式。您还需要在返回的响应中添加 isBase64Encoded 标志。

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

    浏览代码,看起来这仅在函数成功返回时适用,但如果出现任何错误,它会引发异常 - 这是 API Gateway 没有预料到的;因此是 502 Malformed proxy。

    要更清楚地了解这一点,请检查来自控制台和 API 网关的请求之间的区别。由于我们必须设置一个特定的 JSON 有效负载来从控制台(或任何调用服务)调用函数,我会在处理程序之后打印出事件以检查 API 网关请求的事件结构是什么,并在测试时使用它控制台看看是否仍然有效。我猜这样做,它不会像错误声称的那样工作'str object' has no attribute 'lastName'

    如果这适用于控制台中的 API 网关负载,我将检查来自 API 网关的完整请求/响应日志和 Lambda 函数日志(打印事件),以更清楚地了解两个请求。

    【讨论】:

      猜你喜欢
      • 2021-01-08
      • 2022-08-16
      • 1970-01-01
      • 2021-06-16
      • 2018-12-06
      • 1970-01-01
      • 2017-09-07
      • 1970-01-01
      • 2018-04-19
      相关资源
      最近更新 更多