Lambda控制台捕获非致命异常仍报错,寻求合规日志方案
Lambda捕获ClientError后仍触发KeyError,保留调试日志的解决办法
问题情况
在Lambda控制台运行代码时,明明已经捕获了预期的非致命ClientError异常,并且在异常块里加了pass,但还是抛出了KeyError。注释掉异常块里的print语句后问题就消失了,但我想保留调试日志,想问是不是该用logger替代print?
报错详情
{"errorMessage": "'message'", "errorType": "KeyError", "requestId": "47445356-38a2-43ec-98f5-2dde22c6af1f", "stackTrace": [" File \"/var/task/lambda_function.py\", line 11, in lambda_handler\n dynamodb.pushPriceHistoryToDynamo(str(i.name))\n", " File \"/opt/python/dynamodbPushData.py\", line 17, in pushPriceHistoryToDynamo\n response = self.newTable.createPriceHistoryTable(tableName)\n", " File \"/opt/python/createNewTable.py\", line 37, in createPriceHistoryTable\n print(f\"[createNewTable]: {err.response['message']} Table already created\")\n"]}
异常处理代码
def createPriceHistoryTable(self, tableName: str) -> int: try: response = self.dynamodb.create_table( TableName=tableName, KeySchema=[ { 'AttributeName': 'date', 'KeyType': 'HASH' # Hash Key } ], AttributeDefinitions=[ { 'AttributeName': 'date', 'AttributeType': 'S' # string data type } ], ProvisionedThroughput={ 'ReadCapacityUnits': 1, 'WriteCapacityUnits': 50 } ) print("[createNewTable]: New table created") return 200 except ClientError as err: if err.response['ResponseMetadata']['HTTPStatusCode'] == 400: print(f"[createNewTable]: {err.response['message']} Table already created") else: print(f"[createNewTable]: {err.response['message']}") pass return err.response['ResponseMetadata']['HTTPStatusCode']
Lambda主函数代码
import json import dynamodbPushData import RegionIdEnum import ItemIdEnum import time def lambda_handler(event, context): dynamodb = dynamodbPushData.pushData() for i in list(ItemIdEnum.item): dynamodb.pushPriceHistoryToDynamo(str(i.name)) # dynamodb.pushItemOrdersToDynamo(str(i.name)) return { 'statusCode': 200, 'body': json.dumps('Hello from Lambda!') }
解决办法
1. 修复KeyError问题
你遇到的KeyError根本原因是**err.response里没有'message'这个键**,AWS SDK返回的错误信息存在err.response['Error']['Message']路径下,或者直接用err.message属性获取更稳妥。修改后的异常块代码如下:
except ClientError as err: status_code = err.response['ResponseMetadata']['HTTPStatusCode'] error_msg = err.response['Error']['Message'] if status_code == 400: print(f"[createNewTable]: {error_msg} Table already created") else: print(f"[createNewTable]: {error_msg}") return status_code
(pass语句在这里没必要,因为后面已经有return逻辑)
2. 日志推荐用logging替代print
Lambda环境下确实更推荐使用Python的logging模块而非print:
print的输出会直接混入Lambda的日志流,没有级别区分,不利于后续排查问题logging可以设置DEBUG、INFO、ERROR等级别,配合CloudWatch可以更灵活地过滤日志- 能自动集成Lambda的日志上下文,比如请求ID等信息
示例用法:
import logging # 初始化logger logger = logging.getLogger() logger.setLevel(logging.INFO) def createPriceHistoryTable(self, tableName: str) -> int: try: # ... 创建表代码 ... logger.info("[createNewTable]: New table created") return 200 except ClientError as err: status_code = err.response['ResponseMetadata']['HTTPStatusCode'] error_msg = err.response['Error']['Message'] if status_code == 400: logger.info(f"[createNewTable]: {error_msg} Table already created") else: logger.error(f"[createNewTable]: {error_msg}") return status_code
内容的提问来源于stack exchange,提问作者Steven
相关产品推荐
相关产品推荐

