{"record":{"id":"bb7463507566939b","repo":"datawhalechina/hello-agents","slug":"ieee-api-response-status","errorCode":null,"errorMessage":"IEEE API请求失败: {response.status}","messagePattern":"IEEE API请求失败: (.+?)","errorType":"exception","errorClass":"ExternalAPIException","httpStatus":500,"severity":"error","filePath":"Co-creation-projects/Apricity-InnocoreAI/agents/hunter.py","lineNumber":174,"sourceCode":"            return papers\n        \n        # 构建查询参数\n        query = \" OR \".join([f'\"All Meta Data:{keyword}\"' for keyword in keywords])\n        \n        params = {\n            \"apikey\": config.ieee_api_key or \"\",\n            \"querytext\": query,\n            \"max_records\": max_papers * 2,\n            \"start_record\": 1,\n            \"sort_order\": \"desc\",\n            \"sort_field\": \"publication_date\"\n        }\n        \n        try:\n            async with aiohttp.ClientSession() as session:\n                async with session.get(self.ieee_base_url, params=params) as response:\n                    if response.status != 200:\n                        raise ExternalAPIException(f\"IEEE API请求失败: {response.status}\")\n                    \n                    data = await response.json()\n                    \n                    for article in data.get(\"articles\", []):\n                        paper = {\n                            \"id\": article.get(\"article_number\", \"\"),\n                            \"title\": article.get(\"title\", \"\"),\n                            \"authors\": [author.get(\"full_name\", \"\") for author in article.get(\"authors\", {}).get(\"authors\", [])],\n                            \"abstract\": article.get(\"abstract\", \"\"),\n                            \"published\": article.get(\"publication_date\", \"\"),\n                            \"pdf_url\": article.get(\"pdf_url\", \"\"),\n                            \"source\": \"ieee\",\n                            \"doi\": article.get(\"doi\", \"\"),\n                            \"categories\": article.get(\"index_terms\", {}).get(\"ieee_terms\", {}).get(\"terms\", [])\n                        }\n                        \n                        papers.append(paper)\n                        ","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/datawhalechina/hello-agents/blob/606a07d341a47be773fab7f4b71177f53f96b2c3/Co-creation-projects/Apricity-InnocoreAI/agents/hunter.py#L156-L192","documentation":"ExternalAPIException from HunterAgent._search_papers_from_ieee when the GET to ieee_base_url returns non-200. Unlike arXiv, IEEE Xplore requires an API key sent as 'apikey'; the code falls back to \"\" when config.ieee_api_key is unset, so 401/403 (missing/invalid key) and 400 (bad querytext) are the dominant causes, alongside 429 quota exhaustion.","triggerScenarios":"IEEE_API_KEY absent from environment so params['apikey']='' -> 401; expired or over-quota key -> 401/429; querytext with unencoded operators exceeding the API's grammar -> 400; wrong ieee_base_url after an endpoint version change.","commonSituations":"Fresh clone without .env configured; key rotated but process still holds the old value; free-tier weekly quota exhausted mid-run; developer environment where IEEE is enabled by default though no key was ever requested.","solutions":["Set a valid IEEE_XPLORE API key (request at developer.ieee.org) in config/.env and restart.","On 401/403: verify the key is loaded (config.ieee_api_key truthy) before calling, and skip IEEE when it is empty.","On 429: check quota usage on the IEEE developer portal, cache results, and reduce max_records per request.","On 400: simplify querytext to plain quoted keywords and URL-encode via params.","Confirm ieee_base_url matches the current documented endpoint version."],"exampleFix":"# before\nasync def _search_papers_from_iee(...):\n    params = {\"apikey\": config.ieee_api_key or \"\", ...}\n    ... raise ExternalAPIException(f\"IEEE API请求失败: {response.status}\")\n\n# after — fail fast on missing key, make source optional\nasync def _search_papers_from_iee(self, ...):\n    if not config.ieee_api_key:\n        logger.warning(\"IEEE API key 未配置，跳过 IEEE 搜索\")\n        return []\n    params = {\"apikey\": config.ieee_api_key, ...}\n    if response.status == 401:\n        raise ExternalAPIException(\"IEEE API key 无效或未配置\")\n    if response.status != 200:\n        raise ExternalAPIException(f\"IEEE API请求失败: {response.status}\")","handlingStrategy":"validation","validationCode":"# Never call IEEE without a key — validate config first\nif \"ieee\" in sources:\n    if not (config.ieee_api_key or \"\").strip():\n        logger.warning(\"IEEE_API_KEY missing; dropping 'ieee' from sources\")\n        sources = [s for s in sources if s != \"ieee\"]","typeGuard":null,"tryCatchPattern":"try:\n    papers = await hunter._search_papers_from_iee(...)\nexcept ExternalAPIException as e:\n    if \"401\" in str(e) or \"403\" in str(e):\n        logger.error(\"IEEE key invalid/missing — skipping IEEE\")\n        papers = []  # degrade gracefully, arXiv results still flow\n    else:\n        raise","preventionTips":["Request and configure an IEEE Xplore key before enabling the ieee source.","Treat IEEE as an optional source: one failed source should not kill the whole hunt.","Monitor quota (429) and cache responses to conserve the weekly limit."],"tags":["python","ieee","http","auth","rate-limit","network"],"backgroundTag":null,"analyzedSha":"606a07d341a47be773fab7f4b71177f53f96b2c3","analyzedAt":"2026-08-14T22:57:27.446Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}