From fd51d5cfbefa305bbc39288fe3178b05de0e06c8 Mon Sep 17 00:00:00 2001 From: Alpamys Date: Thu, 16 Jul 2026 22:53:19 +0500 Subject: [PATCH] fix(canary): friendly "manifest not found" instead of a raw OS error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Live smoke: `soup data canary check --manifest nope.json` surfaced "[WinError 2] Не удается найти указанный файл: 'nope.json'" -- a raw, locale-dependent OS error leaking straight through from os.path.getsize, where every other Soup command says "File not found: ". --- src/soup_cli/utils/canary.py | 4 ++++ tests/test_v07136.py | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/soup_cli/utils/canary.py b/src/soup_cli/utils/canary.py index d246783..98b2075 100644 --- a/src/soup_cli/utils/canary.py +++ b/src/soup_cli/utils/canary.py @@ -166,6 +166,10 @@ def _harden_permissions(path: str) -> None: def load_manifest(path: str) -> tuple[Canary, ...]: """Read a canary manifest written by :func:`write_manifest`.""" safe = enforce_under_cwd_and_no_symlink(str(path), "manifest") + if not os.path.isfile(safe): + # Without this the caller surfaces a raw (locale-dependent) OS error + # from getsize — e.g. "[WinError 2] Не удается найти указанный файл". + raise ValueError(f"manifest not found: {path}") if os.path.getsize(safe) > _MAX_MANIFEST_BYTES: raise ValueError( f"manifest too large (max {_MAX_MANIFEST_BYTES} bytes)" diff --git a/tests/test_v07136.py b/tests/test_v07136.py index 7b7b376..b8542d4 100644 --- a/tests/test_v07136.py +++ b/tests/test_v07136.py @@ -1430,6 +1430,18 @@ class TestCanaryManifest: generate_canaries(count=1, seed=0), str(tmp_path / "esc.json") ) + def test_missing_manifest_is_a_friendly_message(self, tmp_path, monkeypatch): + """Not a raw locale-dependent OS error. + + Live smoke surfaced "[WinError 2] Не удается найти указанный файл" + leaking straight through from os.path.getsize. + """ + from soup_cli.utils.canary import load_manifest + + monkeypatch.chdir(tmp_path) + with pytest.raises(ValueError, match="manifest not found"): + load_manifest("nope.json") + def test_malformed_manifest_rejected(self, tmp_path, monkeypatch): from pathlib import Path