繁体   English   中英

Python AWS Lambda function 502 Z37A6259CC0C1DAE299A7866489DFF0 正文“内部错误”{}消息

[英]Python AWS Lambda function 502 null body {"message": "Internal server error"}

我正在研究使用 python lambda 为连接到发电机数据库的节流端点提供服务的可行性。 有一个基本的令牌身份验证,并且限制的计数保存在一个 dynamodb 中,TTL 为一天。 我称之为节流,但它实际上是每天的请求计数。 所有复杂的部分都可以工作,如果用户未经身份验证,我会得到预期的响应{"message": "No token, or your token is invalid!"}如果每日请求数用尽,我也会得到预期的消息{"message": "Daily Invocations Exhausted!"}但是,当身份验证和限制允许来自lambda_handler的响应时,我得到一个 502 {"message": "Internal server error"} 当我查看 API 网关测试时,我看到了这个日志:

Mon Nov 29 14:56:28 UTC 2021 : Endpoint response body before transformations: null
Mon Nov 29 14:56:28 UTC 2021 : Execution failed due to configuration error: Malformed Lambda proxy response
Mon Nov 29 14:56:28 UTC 2021 : Method completed with status: 502

当我打印正文并查看 CloudFormation 中的日志时,我看到了这一点:

2021-11-29T15:56:28.103+01:00   {"message": "stuff!"}

我是 python lambdas 的新手,所以我在这里完全不知所措,这种行为对我来说毫无意义,我希望你能在代码中看到我缺少的东西。

import json
import time

# import requests
import boto3
from botocore.exceptions import ClientError

dynamodb = boto3.client('dynamodb')
DAY_LIMIT = 5


def get_token(token):
    try:
        response = dynamodb.get_item(TableName='tokens', Key={'token': {'S': token}})
    except ClientError as e:
        print(e.response['Error']['Message'])
    else:
        return None if 'Item' not in response else response['Item']

def get_token_throttle(token):
    try:
        response = dynamodb.get_item(TableName='token_throttle',
                              Key={'token': {'S': token}})
    except ClientError as e:
        print(e.response['Error']['Message'])
    else:
        return None if 'Item' not in response else response['Item']

def authenticated(function):
    def wrapper(event, context):
        if (event['queryStringParameters'] is None or "token" not in event['queryStringParameters'] or
                get_token(event['queryStringParameters']['token']) is None):
            return {
                "statusCode": 401,
                "body": json.dumps({
                    "message": "No token, or your token is invalid!"
                }),
            }
        else:
            return function(event, context)

    return wrapper


def lambda_limit_per_day(function):
    def wrapper(event, context):
        throttle = get_token_throttle(event['queryStringParameters']['token'])

        if throttle == None:
            dynamodb.put_item(TableName='token_throttle', Item={
                "token": {"S": event['queryStringParameters']['token']},
                "invocations": {"N": str(1)},
                "deletion": {"N": str(int(time.time()) + 86400)}  # one day
            })
            function(event, context)
        elif int(throttle['invocations']['N']) < DAY_LIMIT:
            dynamodb.put_item(TableName='token_throttle', Item={
                "token": {"S": event['queryStringParameters']['token']},
                "invocations": {"N": str(int(throttle['invocations']['N']) + 1)},
                "deletion": {"N": str(throttle['deletion']['N'])}  # one day
            })
            function(event, context)
        else:
            return {
                "statusCode": 200,
                "body": json.dumps({
                    "message": "Daily Invocations Exhausted!"
                }),
            }
    return wrapper


@authenticated
@lambda_limit_per_day
def lambda_handler(event, context):
    """Sample pure Lambda function

    Parameters
    ----------
    event: dict, required
        API Gateway Lambda Proxy Input Format

        Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format

    context: object, required
        Lambda Context runtime methods and attributes

        Context doc: https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html

    Returns
    ------
    API Gateway Lambda Proxy Output Format: dict

        Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
    """
    print("Running Final function")
    body = json.dumps({
            "message": "stuff!"
        })
    print(body)
    return {
        "statusCode": 200,
        "body": body,
    }

您的lambda_handler function 已装饰并具有关联的装饰器 function 名为lambda_limit_per_day 因此,您的 Lambda function 的返回值将是装饰器包装器 function 的返回值。

目前,您的包装器 function 在您处理“未限制”和“在限制范围内”的两条路径中没有返回任何内容——您的代码只是调用function(event, context)但丢弃这些调用的返回值(到lambda_handler修饰函数)。 So, the return value of the wrapper function, and hence your decorated Lambda function, is implicitly None and that's a malformed response , causing API Gateway to generate a 502 response.

将这两个function(event, context)实例更改为:

return function(event, context)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM