fix(question_gen): raise ValueError on UPDATE of missing rows

record_run_end, update_gates, and update_difficulty now check
cursor.rowcount after UPDATE+commit and raise ValueError if 0 rows
were affected. Prevents silent telemetry loss.

Adds three negative-path tests:
- test_record_run_end_missing_run_raises
- test_update_gates_missing_item_raises
- test_update_difficulty_missing_item_raises

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-11 23:23:48 -04:00
parent 7abe92eb1c
commit 9627ac9cf9
2 changed files with 33 additions and 3 deletions
+9 -3
View File
@@ -212,7 +212,7 @@ class QuestionGenStore:
批次统计摘要。
"""
now = datetime.now(tz=UTC).isoformat(timespec="seconds")
self._conn.execute(
cursor = self._conn.execute(
"""
UPDATE question_gen_runs
SET ended_at=?, status=?, total_slots=?, accepted=?, rejected=?, heavy_sampled=?
@@ -229,6 +229,8 @@ class QuestionGenStore:
),
)
self._conn.commit()
if cursor.rowcount == 0:
raise ValueError(f"run_id 不存在: {run_id}")
logger.info(
"出题批次已结束: run_id={}, status={}, accepted={}/{}",
run_id,
@@ -307,7 +309,7 @@ class QuestionGenStore:
属性,每个属性具有 .verdict.value 和 .reason;以及 passed/reject_reason 属性)。
"""
final_status = "accepted" if report.passed else "rejected"
self._conn.execute(
cursor = self._conn.execute(
"""
UPDATE question_gen_items
SET gate_key_verify=?, gate_blind_answer=?, gate_multi_true=?,
@@ -325,6 +327,8 @@ class QuestionGenStore:
),
)
self._conn.commit()
if cursor.rowcount == 0:
raise ValueError(f"item_id 不存在: {item_id}")
def update_difficulty(self, item_id: str, difficulty_steps: int) -> None:
"""更新重量抽检产出的 Agent 步数。
@@ -336,11 +340,13 @@ class QuestionGenStore:
difficulty_steps : int
Agent 完成该题所需步数。
"""
self._conn.execute(
cursor = self._conn.execute(
"UPDATE question_gen_items SET difficulty_steps=? WHERE item_id=?",
(difficulty_steps, item_id),
)
self._conn.commit()
if cursor.rowcount == 0:
raise ValueError(f"item_id 不存在: {item_id}")
def get_run_stats(self, run_id: str) -> RunStats:
"""查询批次统计摘要。