From 750ef91e29db7ddd912ae242a9465622e8b68ebd Mon Sep 17 00:00:00 2001 From: hajimi Date: Sun, 21 Jun 2026 12:32:49 +0800 Subject: [PATCH] fix: expose match live stream task error on failure --- docker/crawler/match_live_stream.py | 30 ++++++++++++------- .../crawler/tests/test_match_live_stream.py | 18 ++++++++++- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/docker/crawler/match_live_stream.py b/docker/crawler/match_live_stream.py index c108a0a..a43a508 100644 --- a/docker/crawler/match_live_stream.py +++ b/docker/crawler/match_live_stream.py @@ -89,6 +89,24 @@ def _fetch_stream_payload(source_url: str, now_ts: int) -> Dict[str, str]: return parse_match_live_detail_html(response.text) +def _build_run_result(candidate_count: int, success_count: int, failed_count: int) -> Dict[str, Any]: + summary_text = ( + f"赛事直播流抓取完成: 待处理 {candidate_count} 条, " + f"成功 {success_count} 条, 失败 {failed_count} 条" + ) + result = { + "success": failed_count == 0, + "candidate_count": candidate_count, + "saved_count": success_count, + "count": success_count, + "failed_count": failed_count, + "summary_text": summary_text, + } + if failed_count > 0: + result["error"] = f"赛事直播流抓取存在失败线路: 失败 {failed_count} 条" + return result + + class TaskFileLock: def __init__(self, name: str, lock_dir: Path | None = None): safe_name = "".join(ch if ch.isalnum() or ch in ("-", "_") else "_" for ch in str(name or "task")) @@ -244,17 +262,7 @@ def run(db_config: Dict[str, Any]) -> Dict[str, Any]: failed_count += 1 candidate_count = len(rows) - return { - "success": failed_count == 0, - "candidate_count": candidate_count, - "saved_count": success_count, - "count": success_count, - "failed_count": failed_count, - "summary_text": ( - f"赛事直播流抓取完成: 待处理 {candidate_count} 条, " - f"成功 {success_count} 条, 失败 {failed_count} 条" - ), - } + return _build_run_result(candidate_count, success_count, failed_count) finally: repo.close() lock.release() diff --git a/docker/crawler/tests/test_match_live_stream.py b/docker/crawler/tests/test_match_live_stream.py index f8fc824..8bfc7cb 100644 --- a/docker/crawler/tests/test_match_live_stream.py +++ b/docker/crawler/tests/test_match_live_stream.py @@ -8,7 +8,12 @@ ROOT = Path(__file__).resolve().parents[1] if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) -from match_live_stream import _build_detail_url, choose_next_fetch_at, parse_match_live_detail_html +from match_live_stream import ( + _build_detail_url, + _build_run_result, + choose_next_fetch_at, + parse_match_live_detail_html, +) class MatchLiveStreamTest(unittest.TestCase): @@ -65,6 +70,17 @@ class MatchLiveStreamTest(unittest.TestCase): "https://json.ncctrials.com/room/7988511/detail.json?v=123456", ) + def test_build_run_result_exposes_top_level_error_for_partial_failure(self): + result = _build_run_result(candidate_count=3, success_count=2, failed_count=1) + + self.assertFalse(result["success"]) + self.assertEqual(result["candidate_count"], 3) + self.assertEqual(result["saved_count"], 2) + self.assertEqual(result["count"], 2) + self.assertEqual(result["failed_count"], 1) + self.assertIn("失败 1 条", result["summary_text"]) + self.assertEqual(result["error"], "赛事直播流抓取存在失败线路: 失败 1 条") + def test_choose_next_fetch_at_uses_60s_for_empty_streams(self): self.assertEqual(choose_next_fetch_at(now_ts=1000, has_existing_stream=False), 1060)