From 16f45774a548b3ab29cc0d28581273a74028f002 Mon Sep 17 00:00:00 2001 From: Quratulain-bilal Date: Thu, 13 Aug 2026 20:36:00 +0500 Subject: [PATCH] fix: narrow bare except Exception in VS Code settings merge (#3844) * fix: narrow bare except Exception in VS Code settings merge Replace overly broad except Exception with (OSError, ValueError, KeyError) to let programming errors like TypeError or AttributeError propagate while still handling expected I/O and parse errors gracefully. * test: verify programming errors propagate through handle_vscode_settings The narrow exception change from 'except Exception' to 'except (OSError, ValueError, KeyError)' was not covered by a regression test. Add a test that monkeypatches merge_json_files to raise TypeError and verifies it propagates rather than being swallowed. --- src/specify_cli/_utils.py | 2 +- tests/test_merge.py | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/specify_cli/_utils.py b/src/specify_cli/_utils.py index b623de81..f2364f6d 100644 --- a/src/specify_cli/_utils.py +++ b/src/specify_cli/_utils.py @@ -213,7 +213,7 @@ def handle_vscode_settings(sub_item, dest_file, rel_path, verbose=False, tracker shutil.copy2(sub_item, dest_file) log("Copied (no existing settings.json):", "blue") - except Exception as e: + except (OSError, ValueError, KeyError) as e: log(f"Warning: Could not merge settings: {e}", "yellow") if not dest_file.exists(): shutil.copy2(sub_item, dest_file) diff --git a/tests/test_merge.py b/tests/test_merge.py index 07cc4688..6b1eb1c2 100644 --- a/tests/test_merge.py +++ b/tests/test_merge.py @@ -1,5 +1,7 @@ import stat +import pytest + from specify_cli import merge_json_files from specify_cli import handle_vscode_settings @@ -188,3 +190,25 @@ def test_handle_vscode_settings_preserves_mode_on_atomic_write(tmp_path): after_mode = stat.S_IMODE(dest_file.stat().st_mode) assert after_mode == before_mode + + +def test_handle_vscode_settings_propagates_programming_errors(tmp_path): + """Unexpected programming errors (TypeError) must propagate, not be silently swallowed.""" + vscode_dir = tmp_path / ".vscode" + vscode_dir.mkdir() + dest_file = vscode_dir / "settings.json" + dest_file.write_text('{"a": 1}\n', encoding="utf-8") + template_file = tmp_path / "template_settings.json" + template_file.write_text('{"b": 2}\n', encoding="utf-8") + + import specify_cli._utils as utils_mod + original_merge = utils_mod.merge_json_files + utils_mod.merge_json_files = lambda *a, **kw: (_ for _ in ()).throw(TypeError("boom")) + try: + with pytest.raises(TypeError): + handle_vscode_settings( + template_file, dest_file, "settings.json", + verbose=False, tracker=None, + ) + finally: + utils_mod.merge_json_files = original_merge