maboloshi/github-chinese · error · RuntimeError
请求失败(重试 {retries} 次后仍失败):{last_err}
Error message
请求失败(重试 {retries} 次后仍失败):{last_err} What it means
fetch() is the script's shared HTTP getter with bounded exponential backoff (time.sleep(2*(attempt+1))) over retries attempts (default 3). It only reaches the final raise for 5xx responses or network-layer exceptions (URLError/timeout/SSL) that survive all retries; 4xx (including 401/403/404/429) are re-raised immediately as urllib.error.HTTPError and never produce this RuntimeError. The message reports the last failure reason but, notably, not the URL that failed.
Source
Thrown at script/ai_review.py:38
def fetch(url: str, headers: dict | None = None, retries: int = 3) -> str:
"""拉取 URL;对 5xx / 网络错误做指数退避重试。"""
req = urllib.request.Request(
url, headers=headers or {"User-Agent": "github-chinese-ai-review"}
)
last_err = ""
for attempt in range(retries):
try:
with urllib.request.urlopen(req, timeout=60) as r:
return r.read().decode("utf-8")
except urllib.error.HTTPError as e:
last_err = f"HTTP {e.code}"
if e.code < 500: # 4xx 不重试
raise
except Exception as e: # noqa: BLE001 - 网络层异常统一重试
last_err = str(e)
time.sleep(2 * (attempt + 1))
raise RuntimeError(f"请求失败(重试 {retries} 次后仍失败):{last_err}")
def main() -> None:
parser = argparse.ArgumentParser(description="AI 代码审查(DeepSeek)")
parser.add_argument("--repo", required=True, help="owner/repo")
parser.add_argument("--pr", required=True, help="PR 编号")
parser.add_argument("--mode", choices=["full", "summary"], default="full")
parser.add_argument("--out", help="输出文件(默认 stdout)")
args = parser.parse_args()
api_key = os.environ.get("LLM_API_KEY")
if not api_key:
print("❌ 缺少环境变量 LLM_API_KEY", file=sys.stderr)
sys.exit(1)
# 1) PR 元数据 + diff
try:
pr_meta = json.loads(fetch(f"https://api.github.com/repos/{args.repo}/pulls/{args.pr}"))View on GitHub (pinned to 1db777260a)
Solutions
- Retry after a short wait — 5xx and transient network errors often clear; rerun the script once connectivity is stable.
- Verify network/proxy: ensure HTTPS_PROXY is set if behind a firewall and that api.github.com resolves (DNS) and TLS completes.
- Increase resilience by raising retries and/or the per-request timeout for the github.com diff endpoint, which can be slow on large PRs.
- If hitting GitHub auth limits, supply a token header to lift the 60/hr anonymous cap (note: 403/429 surface as HTTPError, not this RuntimeError).
Example fix
# before
raise RuntimeError(f"请求失败(重试 {retries} 次后仍失败):{last_err}")
# after — include the URL and status so the caller knows which call failed
raise RuntimeError(f"请求失败(重试 {retries} 次后仍失败):{url} → {last_err}") Defensive patterns
Strategy: retry
Validate before calling
# Before calling fetch(), confirm connectivity to the target host:
import socket
for host in ("api.github.com", "github.com"):
try:
socket.gethostbyname(host)
except OSError as e:
sys.exit(f"❌ 无法解析 {host},请检查 DNS/代理:{e}") Type guard
null
Try / catch
try:
pr_meta = json.loads(fetch(url, retries=3))
except (RuntimeError, urllib.error.HTTPError) as e:
print(f"❌ PR 拉取失败:{e}", file=sys.stderr)
sys.exit(1) Prevention
- Set HTTPS_PROXY in firewalled/VPN environments before running.
- Provide a GitHub token (Authorization: Bearer) to avoid anonymous rate limits where relevant.
- Keep retries >= 3 and let the existing exponential backoff handle transient 5xx.
- Read Retry-After on 429/503 instead of treating every failure as fatal.
When it happens
Trigger: Calling fetch() against api.github.com (PR metadata), github.com (.../pull/N.diff), raw.githubusercontent.com (copilot-instructions.md), and hitting a sustained 5xx from those hosts — or a connection error (DNS, TLS, proxy, read timeout >60s) — for all 3 attempts. Each caller (main()) wraps fetch in its own try/except and exits with a tailored message, so this RuntimeError is the inner cause printed there.
Common situations: api.github.com or github.com briefly 5xx-ing; a flaky proxy or VPN dropping mid-request; an aggressive firewall resetting TLS; GitHub rate-limiting returning 429 (re-raised as HTTPError before exhaustion, so not this message); running the script where LLM_BASE_URL/HTTPS_PROXY is mis-set.
Related errors
AI-assisted analysis of maboloshi/github-chinese@1db777260a (2026-08-13).
Data as JSON: /api/errors/cd63dca27f54985e.
Report an issue: GitHub.