diff --git a/docker/kuma-bridge/app.py b/docker/kuma-bridge/app.py index 22e7f0d..340c9df 100644 --- a/docker/kuma-bridge/app.py +++ b/docker/kuma-bridge/app.py @@ -60,7 +60,9 @@ def _connect() -> UptimeKumaApi: api.disconnect() except Exception: # noqa: BLE001, S110 pass - raise HTTPException(status_code=503, detail=f"Kuma unreachable: {exc}") from exc + # Distinguish "cannot reach" from "rejected us" — very different fixes. + kind = "login rejected" if "username or password" in str(exc).lower() else "unreachable" + raise HTTPException(status_code=503, detail=f"Kuma {kind}: {exc}") from exc _api = api return _api @@ -151,15 +153,18 @@ def _kuma_state() -> tuple[str, str | None]: except Exception as exc: # noqa: BLE001 — connection refused/DNS/timeout return "down", f"HTTP unreachable: {exc}" + # An authenticated, connected session is the real proof: _connect() performs + # the login round-trip, so bad credentials / missing 2FA / an incompatible + # login API all surface here as "down" rather than a false "up". try: - _call(lambda api: _require_live(api) and api.get_monitor_status(0)) + with _lock: + api = _connect() + if not getattr(api, "sio", None) or not api.sio.connected: + _reset() + return "down", "Kuma socket not connected" return "up", None except HTTPException as exc: - # A live call on a bogus id may error while the session is fine — the - # socket being connected is what we actually care about here. - if "not connected" in str(exc.detail): - return "down", str(exc.detail) - return "up", None + return "down", str(exc.detail) except Exception as exc: # noqa: BLE001 — must never 500 return "down", str(exc)