fix: expose match live stream task error on failure
This commit is contained in:
@@ -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)
|
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:
|
class TaskFileLock:
|
||||||
def __init__(self, name: str, lock_dir: Path | None = None):
|
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"))
|
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
|
failed_count += 1
|
||||||
|
|
||||||
candidate_count = len(rows)
|
candidate_count = len(rows)
|
||||||
return {
|
return _build_run_result(candidate_count, success_count, failed_count)
|
||||||
"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} 条"
|
|
||||||
),
|
|
||||||
}
|
|
||||||
finally:
|
finally:
|
||||||
repo.close()
|
repo.close()
|
||||||
lock.release()
|
lock.release()
|
||||||
|
|||||||
@@ -8,7 +8,12 @@ ROOT = Path(__file__).resolve().parents[1]
|
|||||||
if str(ROOT) not in sys.path:
|
if str(ROOT) not in sys.path:
|
||||||
sys.path.insert(0, str(ROOT))
|
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):
|
class MatchLiveStreamTest(unittest.TestCase):
|
||||||
@@ -65,6 +70,17 @@ class MatchLiveStreamTest(unittest.TestCase):
|
|||||||
"https://json.ncctrials.com/room/7988511/detail.json?v=123456",
|
"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):
|
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)
|
self.assertEqual(choose_next_fetch_at(now_ts=1000, has_existing_stream=False), 1060)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user