同步AWS账号标签至example.org时遇索引越界等错误求助
问题分析与修复方案
错误根源
1. 请求头被错误覆盖
你把传入的headers直接改成了字符串"some random value",但requests库要求headers必须是字典类型,这会直接导致请求失败,返回的响应结构完全不符合预期,进而引发后续的索引错误。
2. 未处理value为空的边界情况
虽然你判断了res.get("value"),但如果value是个空列表(比如搜索不到对应应用),直接访问res["value"][0]就会触发list index out of range;而且后面获取appId的代码根本没做判断,不管value有没有内容都硬取索引,肯定会报错。
3. 未校验repoData的结构合法性
repoData["account"]可能是None,或者里面的字段(比如sec_email_address)不存在,直接用下标访问会触发'NoneType' object is not subscriptable或KeyError。
4. 手动拼接JSON容易出错
你用字符串拼接的方式构建patch_data,一旦标签值里包含引号、逗号这类特殊字符,直接就会破坏JSON格式,导致更新请求失败。
修复后的代码
import requests import json import time def add_tags(headers, label, repoData): existing_tag = [] new_list = [] value_quote = [] get_url = f'https://example.org/applications?$search="displayName:{label}"' # 校验请求头格式,不能覆盖传入的合法headers if not isinstance(headers, dict): print("错误:headers必须是字典类型") return None # 捕获请求异常,避免直接崩溃 try: response1 = requests.get(url=get_url, headers=headers) response1.raise_for_status() # 主动抛出HTTP错误(比如404、500) res = response1.json() except requests.exceptions.RequestException as e: print(f"获取应用信息失败: {str(e)}") return None app_info = None # 严格校验响应的value结构,确保能安全取到第一个元素 if res.get("value") and isinstance(res["value"], list) and len(res["value"]) > 0: app_info = res["value"][0] # 处理现有标签,用get避免tags字段不存在的情况 old_tags = app_info.get("tags", []) existing_tag = old_tags.copy() value_quote = [f'"{tag}"' for tag in existing_tag] # 安全获取account数据,避免直接下标访问报错 account_data = repoData.get("account", {}) if not account_data: print("错误:repoData中找不到有效的account数据") return None # 构建新标签,用get避免字段不存在,同时过滤None值 tags = { "SECONDARYCONTACT": account_data.get("sec_email_address"), "PRIMARYCONTACT": account_data.get("primary_email_address"), "COUNTRY": account_data.get("countryID"), "ENVIRONMENT": account_data.get("work_load"), "APPID": account_data.get("application_id"), } tags_list = [] for key, value in tags.items(): if value is not None: tags_list.append(f'"{key}:{value.lower()}"') new_list = tags_list + value_quote # 用json.dumps生成合法JSON,替代手动拼接 patch_data = json.dumps({"tags": new_list}) if not app_info: print("未找到匹配的应用,无法执行标签更新") return None appId = app_info.get("appId") if not appId: print("错误:应用信息中找不到appId") return None time.sleep(30) patch_url = f"https://example.org/applications(appId='{appId}')" try: response2 = requests.patch(url=patch_url, data=patch_data, headers=headers) response2.raise_for_status() return response2 except requests.exceptions.RequestException as e: print(f"更新标签失败: {str(e)}") return None
关键修复说明
- 保留合法请求头:不再覆盖传入的
headers,增加类型校验确保请求格式正确。 - 严格校验响应结构:对
res["value"]的存在性、类型、长度做多层判断,彻底避免索引越界。 - 安全访问字典字段:用
get方法替代直接下标访问,避免KeyError,同时校验核心数据是否存在。 - 用
json.dumps生成请求体:彻底解决手动拼接JSON的格式问题,兼容特殊字符。 - 增加异常捕获:请求过程中任何错误都会被捕获并打印,方便快速定位问题。
内容的提问来源于stack exchange,提问作者Jimmy
相关产品推荐
相关产品推荐

