From 706601416bc81e66841c20ef34c9ec50f4cedc83 Mon Sep 17 00:00:00 2001 From: dekun Date: Sun, 4 Oct 2026 09:48:05 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=AD=E6=8E=A7=E6=8E=A2?= =?UTF-8?q?=E6=B5=8B=E5=AE=A2=E6=88=B7=E7=AB=AF=E7=89=88=E6=9C=AC=E6=97=B6?= =?UTF-8?q?=E9=9D=9E=20JSON=20=E5=93=8D=E5=BA=94=E6=8A=9B=E5=87=BA=20Expec?= =?UTF-8?q?ting=20value=EF=BC=8C=E6=94=B9=E4=B8=BA=E5=8F=AF=E8=AF=BB?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- lib/bridge_client_lib.py | 58 +++++++++++++++++++++++++++++----------- templates/settings.html | 2 +- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/lib/bridge_client_lib.py b/lib/bridge_client_lib.py index 14c12e2..4285c15 100644 --- a/lib/bridge_client_lib.py +++ b/lib/bridge_client_lib.py @@ -33,6 +33,28 @@ def _headers(token: str) -> dict[str, str]: } +def _response_json(r: requests.Response) -> tuple[dict[str, Any] | None, str]: + """安全解析 JSON;失败返回 (None, 可读原因).""" + raw = (r.content or b"").strip() + if not raw: + return None, f"HTTP {r.status_code} 空响应" + try: + data = r.json() + except ValueError: + snippet = raw[:120].decode("utf-8", errors="replace").replace("\n", " ") + hint = "" + if r.status_code in (401, 403): + hint = ";检查 Bridge Token" + elif r.status_code == 404: + hint = ";客户端可能未部署 /api/hub/version(请先手动更新实例)" + elif snippet.lstrip().startswith("<"): + hint = ";收到 HTML(可能被登录页/反代拦截)" + return None, f"HTTP {r.status_code} 非 JSON{hint}: {snippet}" + if not isinstance(data, dict): + return None, f"HTTP {r.status_code} 响应不是对象" + return data, "" + + def fetch_one_snapshot(inst: dict[str, Any]) -> dict[str, Any]: base = (inst.get("base_url") or "").rstrip("/") token = (inst.get("bridge_token") or "").strip() @@ -294,9 +316,9 @@ def fetch_client_version(inst: dict[str, Any]) -> dict[str, Any]: headers={"X-Hub-Token": token, "Accept": "application/json"}, timeout=_timeout(), ) - data = r.json() if r.content else {} - if not isinstance(data, dict): - out["msg"] = f"HTTP {r.status_code}" + data, err = _response_json(r) + if data is None: + out["msg"] = err or f"HTTP {r.status_code}" return out for key in ("sha", "short_sha", "branch", "dirty", "msg", "repo"): if key in data: @@ -304,7 +326,7 @@ def fetch_client_version(inst: dict[str, Any]) -> dict[str, Any]: out["ok"] = bool(data.get("ok")) and r.status_code == 200 out["online"] = out["ok"] if not out["ok"]: - out["msg"] = data.get("msg") or f"HTTP {r.status_code}" + out["msg"] = data.get("msg") or err or f"HTTP {r.status_code}" return out except requests.Timeout: out["msg"] = "超时" @@ -333,14 +355,14 @@ def post_client_update(inst: dict[str, Any]) -> dict[str, Any]: json={}, timeout=_timeout(), ) - data = r.json() if r.content else {} - if not isinstance(data, dict): - data = {"ok": False, "msg": f"HTTP {r.status_code}"} + data, err = _response_json(r) + if data is None: + data = {"ok": False, "msg": err or f"HTTP {r.status_code}"} data["instance_id"] = inst.get("id") data["instance_name"] = inst.get("name") - if r.status_code >= 400 and "ok" not in data: + if r.status_code >= 400 and not data.get("ok"): data["ok"] = False - data.setdefault("msg", f"HTTP {r.status_code}") + data.setdefault("msg", err or f"HTTP {r.status_code}") return data except requests.Timeout: return { @@ -370,12 +392,18 @@ def fetch_backup_list(inst: dict[str, Any]) -> dict[str, Any]: headers={"X-Hub-Token": token, "Accept": "application/json"}, timeout=_timeout(), ) - data = r.json() if r.content else {} - if isinstance(data, dict): - data.setdefault("instance_id", inst.get("id")) - data.setdefault("instance_name", inst.get("name")) - return data - return {"ok": False, "msg": f"HTTP {r.status_code}", "items": []} + data, err = _response_json(r) + if data is None: + return { + "ok": False, + "msg": err or f"HTTP {r.status_code}", + "items": [], + "instance_id": inst.get("id"), + "instance_name": inst.get("name"), + } + data.setdefault("instance_id", inst.get("id")) + data.setdefault("instance_name", inst.get("name")) + return data except Exception as e: return { "ok": False, diff --git a/templates/settings.html b/templates/settings.html index d6269af..226b905 100644 --- a/templates/settings.html +++ b/templates/settings.html @@ -183,7 +183,7 @@ {% endblock %} {% block scripts %} - +