fix(client): identify sku entry failure substage
This commit is contained in:
@@ -30,7 +30,10 @@ from .sku_selection import (
|
||||
SkuPanelDevice,
|
||||
SkuSelectionError,
|
||||
SkuSelectionFlow,
|
||||
_SKU_ENTRY_FAILURE_STAGES,
|
||||
_action_bounds,
|
||||
_annotate_sku_entry_failure,
|
||||
_safe_sku_entry_failure_stage,
|
||||
resolve_task_selection,
|
||||
)
|
||||
|
||||
@@ -48,6 +51,7 @@ _FAILURE_STAGES = frozenset(
|
||||
"device_session",
|
||||
"product_open",
|
||||
"sku_entry",
|
||||
*_SKU_ENTRY_FAILURE_STAGES,
|
||||
"sku_selection",
|
||||
"price_verification",
|
||||
"screenshot_capture",
|
||||
@@ -85,7 +89,11 @@ def safe_failure_stage(error: BaseException) -> str:
|
||||
stage = getattr(error, "_cmbuyer_failure_stage", None)
|
||||
# exact str 避免恶意 str 子类在 hash/eq 中执行任意异常;诊断路径
|
||||
# 自己也必须失败闭合,不能让异常正文越过 CLI 的统一脱敏出口。
|
||||
return stage if type(stage) is str and stage in _FAILURE_STAGES else "unknown"
|
||||
if type(stage) is not str or stage not in _FAILURE_STAGES:
|
||||
return "unknown"
|
||||
if stage in _SKU_ENTRY_FAILURE_STAGES:
|
||||
return stage if _safe_sku_entry_failure_stage(error) == stage else "unknown"
|
||||
return stage
|
||||
except BaseException:
|
||||
return "unknown"
|
||||
|
||||
@@ -101,6 +109,21 @@ def _annotate_failure(error: BaseException, stage: str) -> None:
|
||||
pass
|
||||
|
||||
|
||||
def _failure_stage_for(error: BaseException, runner_stage: str) -> str:
|
||||
if runner_stage == "sku_entry":
|
||||
flow_stage = _safe_sku_entry_failure_stage(error)
|
||||
if flow_stage is not None:
|
||||
return flow_stage
|
||||
return runner_stage
|
||||
|
||||
|
||||
def _annotate_mapped_failure(mapped: BaseException, source: BaseException, runner_stage: str) -> None:
|
||||
stage = _failure_stage_for(source, runner_stage)
|
||||
if stage in _SKU_ENTRY_FAILURE_STAGES:
|
||||
_annotate_sku_entry_failure(mapped, stage)
|
||||
_annotate_failure(mapped, stage)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class SkuSelectionRunResult:
|
||||
"""已发布的截图和无页面正文 manifest 摘要。"""
|
||||
@@ -299,22 +322,22 @@ class SkuSelectionRunner:
|
||||
staging = None
|
||||
except (DeviceConnectionError, ProductUrlError, SkuSelectionRunError, SkuSelectionError) as error:
|
||||
_clean_staging(staging)
|
||||
_annotate_failure(error, stage)
|
||||
_annotate_failure(error, _failure_stage_for(error, stage))
|
||||
raise
|
||||
except (AdbTimeout, HTTPTimeoutError, TimeoutError) as error:
|
||||
_clean_staging(staging)
|
||||
mapped = SkuSelectionRunTimeoutError("规格面板运行超时,未发布任何证据产物。")
|
||||
_annotate_failure(mapped, stage)
|
||||
_annotate_mapped_failure(mapped, error, stage)
|
||||
raise mapped from error
|
||||
except OSError as error:
|
||||
_clean_staging(staging)
|
||||
mapped = SkuSelectionRunError("规格面板证据目录无法创建或发布,未发布任何证据产物。")
|
||||
_annotate_failure(mapped, stage)
|
||||
_annotate_mapped_failure(mapped, error, stage)
|
||||
raise mapped from error
|
||||
except Exception as error:
|
||||
_clean_staging(staging)
|
||||
mapped = SkuSelectionRunError("规格面板运行未完成,未发布任何证据产物。")
|
||||
_annotate_failure(mapped, stage)
|
||||
_annotate_mapped_failure(mapped, error, stage)
|
||||
raise mapped from error
|
||||
finally:
|
||||
# 失败路径只能复用 Flow 的版本、前台和面板证明;证明不了便停止,绝不盲目返回。
|
||||
|
||||
Reference in New Issue
Block a user