{"record":{"id":"147f15b0d14d61cd","repo":"datawhalechina/hello-agents","slug":"max-retries-last-error","errorCode":null,"errorMessage":"请求失败（已重试 {max_retries} 次）: {last_error}","messagePattern":"请求失败（已重试 (.+?) 次）: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"Co-creation-projects/chengH425-PaperAssistant/src/literature_tool.py","lineNumber":226,"sourceCode":"                        continue\n                    raise RuntimeError(\n                        \"API 请求频率已达上限（429 Too Many Requests）。\\n\"\n                        \"Semantic Scholar 免费额度为 100 次/5 分钟。\\n\"\n                        \"请稍等 1-5 分钟后重试，或申请免费 API Key：\\n\"\n                        \"https://www.semanticscholar.org/product/api\\n\"\n                        \"获取后在 .env 中设置 SEMANTIC_SCHOLAR_API_KEY\"\n                    ) from e\n                raise RuntimeError(\n                    f\"Semantic Scholar API 返回 HTTP {e.code}: {e.reason}\"\n                ) from e\n            except urllib.error.URLError as e:\n                last_error = e\n                if attempt < max_retries - 1:\n                    time.sleep(2 ** (attempt + 1))\n                    continue\n                raise RuntimeError(f\"网络连接失败: {str(e.reason)}\") from e\n\n        raise RuntimeError(f\"请求失败（已重试 {max_retries} 次）: {last_error}\")\n\n    def run(self, parameters: Dict[str, Any]) -> ToolResponse:\n        keyword = parameters.get(\"keyword\", \"\")\n        author = parameters.get(\"author\", \"\")\n        field = parameters.get(\"field\", \"\")\n\n        if not keyword and not author:\n            return ToolResponse.error(\n                code=\"INVALID_PARAM\",\n                message=\"请至少提供关键词（keyword）或作者（author）\"\n            )\n\n        url = self._build_url(parameters)\n        api_key = os.getenv(\"SEMANTIC_SCHOLAR_API_KEY\", \"\")\n\n        try:\n            data = self._make_request(url, api_key)\n","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/datawhalechina/hello-agents/blob/606a07d341a47be773fab7f4b71177f53f96b2c3/Co-creation-projects/chengH425-PaperAssistant/src/literature_tool.py#L208-L244","documentation":"The final fall-through RuntimeError in the Semantic Scholar request loop: it fires only if the for-loop completes without returning or raising, carrying the last URLError observed. Message: 'request failed (retried {max_retries} times): {last_error}'. It is a defensive exhaust-path covering transient network errors that survived all retries.","triggerScenarios":"Every retry attempt raises URLError (persistent offline state, unreachable proxy) — each iteration sleeps and continues, and after the last attempt the loop exits to this raise. Note: per-attempt HTTPError paths raise earlier, so this line is reached mainly via the URLError branch.","commonSituations":"Extended network outages, misconfigured proxy that consistently fails, or flaky Wi-Fi where 2s/4s backoff is not enough for recovery.","solutions":["Inspect `{last_error}` in the message — it names the actual network failure to fix (DNS, refused, timeout).","Stabilize connectivity or fix proxy settings, then retry the tool call.","Increase max_retries/backoff if transient flakiness is expected in your environment.","Treat as non-retryable at the caller level: the client already retried; immediate re-calls will likely fail too."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    data = _request(url)\nexcept RuntimeError as e:\n    if \"已重试\" in str(e):\n        # client already exhausted its retries with short backoff;\n        # back off much longer before the next attempt\n        time.sleep(120)\n        data = _request(url)\n    else:\n        raise","preventionTips":["Don't immediately re-call after this error — the network issue outlasted 2s/4s/8s backoff.","Check the embedded last_error text; it names the real failure (DNS/refused/timeout).","For flaky networks, wrap tool calls with a longer outer retry cadence."],"tags":["network","retry-exhausted","urllib","semantic-scholar","python"],"backgroundTag":null,"analyzedSha":"606a07d341a47be773fab7f4b71177f53f96b2c3","analyzedAt":"2026-08-14T22:57:27.446Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}