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
+25 -16
View File
@@ -36,6 +36,20 @@ CollectServiceFactory = Callable[
[str, str, Callable[[], bool]], PddCollectService
]
_QUEUE_BLOCKING_ERROR_CODES = frozenset(
{
"DEVICE_APP_START_FAILED",
"DEVICE_DISCONNECTED",
"DEVICE_NOT_FOUND",
"DEVICE_OFFLINE",
"DEVICE_SESSION_CLOSED",
"DEVICE_UNAUTHORIZED",
"PDD_PAGE_CAPTCHA",
"PDD_PAGE_LOGIN_REQUIRED",
"PDD_PAGE_UNKNOWN",
}
)
class CollectTaskService:
"""一次调用只处理一条本地工作或一个待提交事件。"""
@@ -149,13 +163,16 @@ class CollectTaskService:
collector = self._factory(
self._device_address, self._client.client_id, self._cancelled
)
business_failure_message = ""
failure_message = ""
queue_blocked = False
try:
result = collector.collect(started.task)
event = self._repository.save_collect_result(
remote_task_id, started.attempt_id, result.to_pdd_data()
)
except PddCollectError as exc:
failure_message = exc.message
queue_blocked = exc.code in _QUEUE_BLOCKING_ERROR_CODES
status, retryable = self._classify_error(exc.code)
report_code = self._report_error_code(exc.code)
event = self._repository.save_collect_failure(
@@ -169,12 +186,12 @@ class CollectTaskService:
)
if exc.code == "PDD_CANCELLED":
return self._submit_cancelled(event, remote_task_id)
if exc.code == "PDD_GOODS_UNAVAILABLE":
business_failure_message = exc.message
outcome = self._submit(event)
if business_failure_message and outcome.kind == "failed":
if failure_message and outcome.kind == "failed":
return CollectTaskOutcome(
"business_failed", business_failure_message, remote_task_id
"global_failed" if queue_blocked else "task_failed",
f"任务 {remote_task_id} 采集失败:{failure_message}",
remote_task_id,
)
return outcome
@@ -239,18 +256,10 @@ class CollectTaskService:
return TaskStatus.CANCELLED, False
if code == "PDD_GOODS_UNAVAILABLE":
return TaskStatus.FAILED, False
if code in {
"PDD_PAGE_LOGIN_REQUIRED",
"PDD_PAGE_CAPTCHA",
"PDD_DATA_SPEC_INCOMPLETE",
"PDD_DATA_TITLE_MISSING",
"PDD_DATA_PRICE_MISSING",
"PDD_DATA_SKU_NAME_TRUNCATED",
}:
if code in {"PDD_PAGE_LOGIN_REQUIRED", "PDD_PAGE_CAPTCHA"}:
return TaskStatus.MANUAL_REVIEW, False
if code.startswith("PDD_DATA_GOODS_"):
return TaskStatus.FAILED, False
return TaskStatus.RETRY_WAIT, True
# 自动流程只执行一次。失败任务由用户明确点击“重新采集”后再运行。
return TaskStatus.FAILED, False
@staticmethod
def _report_error_code(code: str) -> str: