From f8c3bfd88e6ce2be020eb3cca391778e1f933e8d Mon Sep 17 00:00:00 2001 From: Open Date: Mon, 1 Jun 2026 02:59:34 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=81=A5=E5=BA=B7=E6=A3=80?= =?UTF-8?q?=E6=9F=A5=E7=95=B8=E5=BD=A2=20URL=20=E5=AF=BC=E8=87=B4=20traceb?= =?UTF-8?q?ack?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - derive_health_url() 捕获 ValueError 并抛中文 RuntimeError - wait_for_health() 先推导健康检查 URL,无效 URL 立即失败不重试 - 新增回归测试覆盖畸形 URL 推导和不重试 --- tests/test_vibe_update.py | 17 +++++++++++++++++ vibe_update.py | 8 ++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/tests/test_vibe_update.py b/tests/test_vibe_update.py index 86b486f..4300510 100644 --- a/tests/test_vibe_update.py +++ b/tests/test_vibe_update.py @@ -228,6 +228,10 @@ def test_derive_health_url_drops_status_query_parameters(self): "http://localhost:8080/api/health", ) + def test_derive_health_url_reports_invalid_url_without_traceback(self): + with self.assertRaisesRegex(RuntimeError, "无效的 InkDash URL"): + vibe_update.derive_health_url("http://[::1") + def test_format_health_summary(self): summary = vibe_update.format_health_summary({ "status": "ok", @@ -295,6 +299,19 @@ def test_wait_for_health_times_out_with_last_error(self): monotonic_fn=iter([0.0, 0.0]).__next__, ) + def test_wait_for_health_rejects_invalid_url_before_retry(self): + with patch("vibe_update.request_vibe") as request_mock: + with self.assertRaisesRegex(RuntimeError, "无效的 InkDash URL"): + vibe_update.wait_for_health( + "http://[::1", + request_timeout=0.1, + wait_timeout=2.0, + wait_interval=0.1, + sleep_fn=lambda _: self.fail("invalid URL should not sleep"), + ) + + request_mock.assert_not_called() + def test_request_vibe_reports_invalid_json_without_traceback(self): with patch("vibe_update.request.urlopen", return_value=FakeResponse(b"not json")): with self.assertRaisesRegex(RuntimeError, "不是有效 JSON"): diff --git a/vibe_update.py b/vibe_update.py index c5ee33b..02bd898 100644 --- a/vibe_update.py +++ b/vibe_update.py @@ -311,7 +311,10 @@ def request_vibe( def derive_health_url(url: str) -> str: - parsed = urlparse(url.rstrip("/")) + try: + parsed = urlparse(url.rstrip("/")) + except ValueError as e: + raise RuntimeError(f"无效的 InkDash URL:{e}") from e path = parsed.path.rstrip("/") for suffix in ("/api/vibe", "/api/status", "/api/health"): if path.endswith(suffix): @@ -405,13 +408,14 @@ def wait_for_health( sleep_fn=time.sleep, monotonic_fn=time.monotonic, ) -> Dict[str, Any]: + health_url = derive_health_url(url) deadline = monotonic_fn() + max(0.0, wait_timeout) interval = max(0.1, wait_interval) last_error = "" while True: try: - return request_vibe(derive_health_url(url), None, request_timeout, token) + return request_vibe(health_url, None, request_timeout, token) except RuntimeError as e: last_error = str(e)