From 4555fd26f4ed9018589c1078e3f26fe54606207b Mon Sep 17 00:00:00 2001 From: rroskam Date: Thu, 14 May 2026 22:30:39 -0400 Subject: [PATCH] refactor: use custom error types consistently in store.py and linker.py Closes #51 - Wrap OSError in place_skill() with PlacementError (from errors.py) - linker.py now raises PlacementError for filesystem failures - Move __version__ and NAPOLN_DIR imports to module level - NAPOLN_DIR constant added to core/home.py --- src/napoln/core/linker.py | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/src/napoln/core/linker.py b/src/napoln/core/linker.py index a929db8..699132e 100644 --- a/src/napoln/core/linker.py +++ b/src/napoln/core/linker.py @@ -12,6 +12,7 @@ from napoln.core.home import NAPOLN_DIR from napoln.core._version import __version__ +from napoln.errors import PlacementError def _reflink_copy(src: Path, dst: Path) -> None: @@ -64,18 +65,43 @@ def place_skill(store_path: Path, target_dir: Path) -> str: Returns: "clone" or "copy" depending on the link mode used. + + Raises: + PlacementError: If placement fails due to filesystem issues. """ - if target_dir.exists(): - shutil.rmtree(target_dir) + try: + if target_dir.exists(): + shutil.rmtree(target_dir) + except OSError as e: + raise PlacementError( + f"Failed to remove existing placement directory: {target_dir}", + cause=str(e), + fix="Check file permissions and ensure no other process is using the directory.", + ) from e + + try: + target_dir.mkdir(parents=True, exist_ok=True) + except OSError as e: + raise PlacementError( + f"Failed to create placement directory: {target_dir}", + cause=str(e), + fix="Check parent directory permissions.", + ) from e - target_dir.mkdir(parents=True, exist_ok=True) link_mode: str | None = None for src_file in sorted(store_path.rglob("*")): if src_file.is_file(): rel = src_file.relative_to(store_path) dst_file = target_dir / rel - dst_file.parent.mkdir(parents=True, exist_ok=True) + try: + dst_file.parent.mkdir(parents=True, exist_ok=True) + except OSError as e: + raise PlacementError( + f"Failed to create directory: {dst_file.parent}", + cause=str(e), + fix="Check parent directory permissions.", + ) from e mode = clone_file(src_file, dst_file) if link_mode is None: link_mode = mode