feat: 任务失败后继续执行下一条 (#170)

This commit is contained in:
chengma
2026-08-11 18:21:25 +08:00
parent b2c99840b3
commit 8b8a542cc5
14 changed files with 280 additions and 103 deletions
+65 -3
View File
@@ -157,7 +157,7 @@ class CollectTaskServiceTest(unittest.TestCase):
calls, PddCollectError("PDD_PAGE_CAPTCHA", "需要验证")
).execute_one()
self.assertEqual(outcome.kind, "failed")
self.assertEqual(outcome.kind, "global_failed")
self.assertEqual(
self.repository.get_task("COL-001").status,
TaskStatus.MANUAL_REVIEW,
@@ -170,13 +170,75 @@ class CollectTaskServiceTest(unittest.TestCase):
[], PddCollectError("PDD_GOODS_UNAVAILABLE", message)
).execute_one()
self.assertEqual("business_failed", outcome.kind)
self.assertEqual(message, outcome.message)
self.assertEqual("task_failed", outcome.kind)
self.assertIn(message, outcome.message)
detail = self.repository.get_task("COL-001")
self.assertEqual(TaskStatus.FAILED, detail.status)
self.assertEqual("PDD_GOODS_UNAVAILABLE", detail.last_error_code)
self.assertEqual(1, self.gateway.submission_count)
def test_page_timeout_fails_once_without_automatic_retry(self):
message = "等待商品页加载超时"
outcome = self._service(
[], PddCollectError("PDD_PAGE_TIMEOUT", message)
).execute_one()
self.assertEqual("task_failed", outcome.kind)
detail = self.repository.get_task("COL-001")
self.assertEqual(TaskStatus.FAILED, detail.status)
self.assertEqual(0, detail.retry_count)
self.assertIn(message, outcome.message)
def test_task_failure_does_not_block_next_local_task(self):
# 直接准备两条本地任务,验证失败任务不会再次被自动选中。
for task_id in ("COL-FIRST", "COL-SECOND"):
self.repository.add_claimed_task(
NewClaimedTask(
remote_task_id=task_id,
task_type=TaskType.COLLECT,
goods_url=f"https://example.test/{task_id}",
)
)
calls = []
class AcceptGateway:
def submit_failure(self, *_args):
return SubmissionReceipt(
True, "FAILURE-001", "2026-08-11T08:00:00Z"
)
def submit_result(self, *_args):
return SubmissionReceipt(
True, "RESULT-001", "2026-08-11T08:00:01Z"
)
def service(error=None):
return CollectTaskService(
AcceptGateway(),
self.repository,
self.client,
"USB-001",
collect_service_factory=lambda *_args: FakeCollector(calls, error),
)
first = service(
PddCollectError("PDD_PAGE_TIMEOUT", "第一页加载超时")
).execute_one()
second = service().execute_one()
self.assertEqual("task_failed", first.kind)
self.assertEqual("succeeded", second.kind)
self.assertEqual(calls, ["COL-FIRST", "COL-SECOND"])
self.assertEqual(
TaskStatus.FAILED,
self.repository.get_task("COL-FIRST").status,
)
self.assertEqual(
TaskStatus.SUCCEEDED,
self.repository.get_task("COL-SECOND").status,
)
def test_execute_selected_only_runs_requested_local_task(self):
for task_id in ("COL-SELECTED", "COL-OTHER"):
self.repository.add_claimed_task(