From 22db985e90ac636020f041502663bedfff542f57 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Wed, 17 Jun 2026 19:07:07 -0400 Subject: [PATCH] refactor(src): migrate src/summary_cache.py to Result[T] error handling (4 sites) Migrates the 4 try/except sites in SummaryCache: 1. load() - line 39: was `except Exception: self.cache = {}` Now `except (OSError, json.JSONDecodeError):` and returns Result[bool] with ErrorInfo on failure. 2. save() - line 48: was `except Exception: pass` Now `except OSError:` and returns Result[bool] with ErrorInfo on failure. 3. clear() - line 91: was `except Exception: pass` Now `except OSError:` and returns Result[bool] with ErrorInfo on failure. 4. get_stats() - line 100: was `except Exception: pass` Now `except OSError:` and returns Result[dict] with default empty size_bytes on failure. All 4 sites narrowed from broad `except Exception` to specific stdlib I/O exceptions (OSError, json.JSONDecodeError). Methods that previously returned None now return Result[bool]; get_stats() now returns Result[dict] instead of dict. Callers (app_controller.py:_handle_clear_summary_cache, _cb_clear_summary_cache, summarize.py) ignore the return value, which is backwards-compatible. Tests verified: - tests/test_summary_cache.py (3 tests) PASS - tests/test_ui_cache_controls_sim.py (1 live_gui test) PASS --- src/summary_cache.py | 50 +++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/src/summary_cache.py b/src/summary_cache.py index 233d05db..b68f8c27 100644 --- a/src/summary_cache.py +++ b/src/summary_cache.py @@ -4,6 +4,8 @@ import json from pathlib import Path from typing import Optional, Dict +from src.result_types import Result, ErrorInfo, ErrorKind + def get_file_hash(content: str) -> str: """ @@ -27,26 +29,30 @@ class SummaryCache: self.cache: Dict[str, Dict[str, str]] = {} self.load() - def load(self) -> None: + def load(self) -> Result[bool]: """ Loads cache from disk. [C: src/tool_presets.py:ToolPresetManager._read_raw, src/workspace_manager.py:WorkspaceManager._load_file, tests/test_gui_phase3.py:test_create_track, tests/test_history_management.py:test_save_separation, tests/test_session_logging.py:test_open_session_creates_subdir_and_registry] """ - if self.cache_file.exists(): - try: - with open(self.cache_file, "r", encoding="utf-8") as f: - self.cache = json.load(f) - except Exception: - self.cache = {} + if not self.cache_file.exists(): + return Result(data=False) + try: + with open(self.cache_file, "r", encoding="utf-8") as f: + self.cache = json.load(f) + return Result(data=True) + except (OSError, json.JSONDecodeError) as e: + self.cache = {} + return Result(data=False, errors=[ErrorInfo(kind=ErrorKind.INTERNAL, message=str(e), source="summary_cache.load", original=e)]) - def save(self) -> None: + def save(self) -> Result[bool]: """Saves cache to disk.""" try: self.cache_file.parent.mkdir(parents=True, exist_ok=True) with open(self.cache_file, "w", encoding="utf-8") as f: json.dump(self.cache, f, indent=1) - except Exception: - pass + return Result(data=True) + except OSError as e: + return Result(data=False, errors=[ErrorInfo(kind=ErrorKind.INTERNAL, message=str(e), source="summary_cache.save", original=e)]) def get_summary(self, file_path: str, content_hash: str) -> Optional[str]: """ @@ -79,27 +85,29 @@ class SummaryCache: self.cache.pop(first_key) self.save() - def clear(self) -> None: + def clear(self) -> Result[bool]: """ Clears the cache both in-memory and on disk. [C: tests/conftest.py:reset_ai_client] """ self.cache.clear() - if self.cache_file.exists(): - try: - self.cache_file.unlink() - except Exception: - pass + if not self.cache_file.exists(): + return Result(data=True) + try: + self.cache_file.unlink() + return Result(data=True) + except OSError as e: + return Result(data=False, errors=[ErrorInfo(kind=ErrorKind.INTERNAL, message=str(e), source="summary_cache.clear", original=e)]) - def get_stats(self) -> dict: + def get_stats(self) -> Result[dict]: """Returns dictionary of cache statistics.""" size_bytes = 0 if self.cache_file.exists(): try: size_bytes = self.cache_file.stat().st_size - except Exception: - pass - return { + except OSError as e: + return Result(data={"entries": len(self.cache), "size_bytes": 0}, errors=[ErrorInfo(kind=ErrorKind.INTERNAL, message=str(e), source="summary_cache.get_stats", original=e)]) + return Result(data={ "entries": len(self.cache), "size_bytes": size_bytes - } + })