在AWS Lambda中用Python解析SNS JSON消息遇类型错误问题
解决AWS Lambda解析SNS JSON消息的TypeError问题
嘿,我之前也踩过这个坑!你碰到的TypeError: string indices must be integers本质原因很直白:你直接把SNS消息里的Message字段当成Python字典来访问了,但实际上这个Message是JSON格式的字符串,不是已经解析好的字典类型。
为什么会出错?
SNS传递消息时,会把实际业务内容以JSON字符串的形式封装在Message字段里。比如你打印event['Records'][0]['Sns']['Message'],会看到类似这样的输出:
"{\"EC2InstanceId\": \"i-1234567890abcdef0\", \"Event\": \"autoscaling:TEST_NOTIFICATION\"}"
这是一个纯字符串,不是字典结构,所以你用msg['EC2InstanceId']去访问自然会报错——字符串只能用整数下标(比如msg[0]),根本不支持用字符串当键。
修复步骤
只需要多做一步:用json.loads()把这个JSON字符串解析成Python字典,之后就能正常访问字段了。
错误代码示例(你的原始写法)
import json def lambda_handler(event, context): msg = event['Records'][0]['Sns']['Message'] instance_id = msg['EC2InstanceId'] # 这里触发TypeError return { 'statusCode': 200, 'body': json.dumps('Success') }
修正后的代码
import json def lambda_handler(event, context): # 先取出SNS的消息字符串 msg_str = event['Records'][0]['Sns']['Message'] # 把字符串解析成Python字典 msg_dict = json.loads(msg_str) # 现在可以正常访问EC2InstanceId了 instance_id = msg_dict['EC2InstanceId'] print(f"处理的EC2实例ID: {instance_id}") return { 'statusCode': 200, 'body': json.dumps(f"成功处理实例 {instance_id}") }
额外建议:加上异常处理
为了让你的Lambda函数更健壮,建议加上异常捕获,处理解析失败或者字段不存在的情况:
import json def lambda_handler(event, context): try: # 逐层获取SNS消息字符串 record = event['Records'][0] sns_msg = record['Sns']['Message'] # 解析JSON msg_dict = json.loads(sns_msg) # 获取实例ID instance_id = msg_dict['EC2InstanceId'] print(f"处理的EC2实例ID: {instance_id}") return { 'statusCode': 200, 'body': json.dumps(f"成功处理实例 {instance_id}") } except (KeyError, json.JSONDecodeError) as e: error_msg = f"处理消息失败: {str(e)}" print(error_msg) return { 'statusCode': 400, 'body': json.dumps(error_msg) }
这样就算消息格式不符合预期,你的函数也能返回友好的错误信息,而不是直接崩溃。
内容的提问来源于stack exchange,提问作者Jeff Carson
相关产品推荐
相关产品推荐

