![](/img/trans.png)
[英]AWS Lambda-API gateway "message": "Internal server error" (502 Bad Gateway)
[英]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.