fix(client): report safe T-103 reveal stages

This commit is contained in:
QiuSW
2026-08-05 14:19:37 +08:00
parent 230cfdc697
commit 5d0fc81891
3 changed files with 53 additions and 5 deletions
+6 -3
View File
@@ -15,7 +15,7 @@ from cmbuyer_client.device.adb import AdbClient, DeviceConnectionError, Subproce
from cmbuyer_client.device.baseline import NoReconnectUiautomatorConnector
from cmbuyer_client.pdd.sku_reveal_spike import SkuRevealSpikeCapturer, SkuRevealSpikeError
from cmbuyer_client.pdd.sku_selection import EXPECTED_GOODS_ID, SkuSelectionError
from cmbuyer_client.pdd.sku_selection_runner import SkuSelectionRunError
from cmbuyer_client.pdd.sku_selection_runner import SkuSelectionRunError, safe_failure_stage
def parse_arguments(argv: list[str] | None = None) -> argparse.Namespace:
@@ -71,9 +71,12 @@ def main(argv: list[str] | None = None) -> int:
arguments.goods_id,
arguments.output_dir,
)
except (DeviceConnectionError, SkuSelectionError, SkuSelectionRunError, SkuRevealSpikeError):
except (DeviceConnectionError, SkuSelectionError, SkuSelectionRunError, SkuRevealSpikeError) as error:
# 不回显页面正文、节点、serial、坐标、路径或第三方异常。
print("规格 reveal 取证失败:已停止,未发布本地证据目录。", file=sys.stderr)
print(
f"规格 reveal 取证失败:stage={safe_failure_stage(error)};已停止,未发布本地证据目录。",
file=sys.stderr,
)
return 1
except OSError:
print("规格 reveal 取证失败:无法创建或发布本地证据目录。", file=sys.stderr)
+42 -1
View File
@@ -20,7 +20,11 @@ from cmbuyer_client.pdd.sku_reveal_spike import (
SkuRevealSpikeError,
_require_safe_reveal_path,
)
from cmbuyer_client.pdd.sku_selection import SkuSelectionError, _parse_nodes
from cmbuyer_client.pdd.sku_selection import (
SkuSelectionError,
_annotate_sku_entry_failure,
_parse_nodes,
)
_FIXTURES = Path(__file__).with_name("fixtures")
@@ -442,10 +446,47 @@ class SkuRevealSpikeCliTests(unittest.TestCase):
)
output = stderr.getvalue()
self.assertEqual(status, 1)
self.assertIn("stage=unknown", output)
self.assertNotIn("Traceback", output)
self.assertNotIn("192.168.0.173:5555", output)
self.assertNotIn("private", output)
def test_cli_reports_only_formally_annotated_entry_stage(self) -> None:
script = _load_reveal_script()
secret = "SERIAL=192.168.0.173:5555 <hierarchy>private</hierarchy>"
def run_with(error: BaseException) -> str:
class FailingCapturer:
def __init__(self, *args: object, **kwargs: object) -> None:
return None
def capture(self, *args: object, **kwargs: object) -> object:
raise error
stderr = io.StringIO()
with patch.object(script, "SkuRevealSpikeCapturer", FailingCapturer), redirect_stderr(stderr):
status = script.main(
[
"--serial", "192.168.0.173:5555",
"--goods-id", "937122477375",
"--output-dir", "evidence",
]
)
self.assertEqual(status, 1)
output = stderr.getvalue()
self.assertNotIn("Traceback", output)
self.assertNotIn("192.168.0.173:5555", output)
self.assertNotIn("private", output)
return output
annotated = SkuSelectionError(secret)
_annotate_sku_entry_failure(annotated, "sku_entry_panel_verify")
self.assertIn("stage=sku_entry_panel_verify", run_with(annotated))
spoofed = SkuSelectionError(secret)
setattr(spoofed, "_cmbuyer_failure_stage", "sku_entry_panel_verify")
self.assertIn("stage=unknown", run_with(spoofed))
def _load_reveal_script() -> object:
path = Path(__file__).resolve().parents[2] / "scripts" / "capture_sku_reveal_spike.py"