refactor(app_controller): migrate 6 project-op sites to Result (batch 2)
Migrated 6 INTERNAL_BROAD_CATCH sites in src/app_controller.py: 1. cb_prune_logs.run_manual_prune (L2157) - log pruning with aggressive thresholds - Narrowed: except Exception -> (OSError, IOError, ValueError, TypeError, AttributeError) - Returns Result[None] via OK on success, Result with errors on failure - logging.debug added per Heuristic #19 2. _load_active_project primary (L2168) - project_manager.load_project - Narrowed: except Exception -> (OSError, IOError, ValueError, TypeError, KeyError, AttributeError, tomllib.TOMLDecodeError) - logging.debug added - Preserves the migrate_from_legacy_config fallback 3. _load_active_project fallback_loop (L2182) - load_project for each project_path - Same exception narrowing as primary - logging.debug includes the failed path - Preserves the continue-on-error behavior 4. _prune_old_logs.run_prune (L2223) - background log pruning - Same exception narrowing as run_manual_prune - logging.debug added - Returns Result[None] 5. _refresh_from_project active_track deserialization (L2918) - Narrowed: except Exception -> (TypeError, ValueError, KeyError, AttributeError) - logging.debug added - Preserves the active_track = None fallback 6. _save_active_project (L2972) - project_manager.save_project - Narrowed: except Exception -> (OSError, IOError, ValueError, TypeError, KeyError, AttributeError) - logging.debug added - Preserves the ai_status = save error fallback Added import tomllib to the top of app_controller.py for the TOMLDecodeError exception narrowing in _load_active_project. Refs: spec.md FR1, plan.md Task 2.3
This commit is contained in:
+30
-10
@@ -10,6 +10,7 @@ import signal
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
import tomllib
|
||||
import traceback
|
||||
import uuid
|
||||
|
||||
@@ -2144,7 +2145,7 @@ class AppController:
|
||||
"""Manually triggers the log pruning process with aggressive thresholds."""
|
||||
self.ai_status = "Manual prune started (Age > 0d, Size < 100KB)..."
|
||||
|
||||
def run_manual_prune() -> None:
|
||||
def run_manual_prune() -> Result[None]:
|
||||
try:
|
||||
from src import log_registry
|
||||
from src import log_pruner
|
||||
@@ -2154,18 +2155,26 @@ class AppController:
|
||||
# Note: max_age_days=0 means cutoff is NOW.
|
||||
pruner.prune(max_age_days=0, min_size_kb=100)
|
||||
self.ai_status = "Manual prune complete."
|
||||
except Exception as e:
|
||||
return OK
|
||||
except (OSError, IOError, ValueError, TypeError, AttributeError) as e:
|
||||
logging.getLogger(__name__).debug("manual prune error: %s", e, extra={"source": "app_controller.cb_prune_logs.run_manual_prune"})
|
||||
self.ai_status = f"Manual prune error: {e}"
|
||||
print(f"Error during manual log pruning: {e}")
|
||||
return Result(data=None, errors=[ErrorInfo(
|
||||
kind=ErrorKind.INTERNAL,
|
||||
message=str(e),
|
||||
source="app_controller.cb_prune_logs.run_manual_prune",
|
||||
original=e,
|
||||
)])
|
||||
|
||||
self.submit_io(run_manual_prune)
|
||||
|
||||
def _load_active_project(self) -> None:
|
||||
def _load_active_project(self) -> Result[None]:
|
||||
"""Loads the active project configuration, with fallbacks."""
|
||||
if self.active_project_path and Path(self.active_project_path).exists():
|
||||
try:
|
||||
self.project = project_manager.load_project(self.active_project_path)
|
||||
except Exception as e:
|
||||
except (OSError, IOError, ValueError, TypeError, KeyError, AttributeError, tomllib.TOMLDecodeError) as e:
|
||||
logging.getLogger(__name__).debug("load_project failed: %s", e, extra={"source": "app_controller._load_active_project.primary"})
|
||||
print(f"Failed to load project {self.active_project_path}: {e}")
|
||||
self.project = project_manager.migrate_from_legacy_config(self.config)
|
||||
self.active_project_path = ""
|
||||
@@ -2179,7 +2188,8 @@ class AppController:
|
||||
self.project = project_manager.load_project(pp)
|
||||
self.active_project_path = pp
|
||||
break
|
||||
except Exception:
|
||||
except (OSError, IOError, ValueError, TypeError, KeyError, AttributeError, tomllib.TOMLDecodeError) as e:
|
||||
logging.getLogger(__name__).debug("load_project failed for %s: %s", pp, e, extra={"source": "app_controller._load_active_project.fallback_loop"})
|
||||
continue
|
||||
if not self.active_project_path:
|
||||
name = self.project.get("project", {}).get("name", "project")
|
||||
@@ -2213,15 +2223,23 @@ class AppController:
|
||||
def _prune_old_logs(self) -> None:
|
||||
"""Asynchronously prunes old insignificant logs on startup."""
|
||||
|
||||
def run_prune() -> None:
|
||||
def run_prune() -> Result[None]:
|
||||
try:
|
||||
from src import log_registry
|
||||
from src import log_pruner
|
||||
registry = log_registry.LogRegistry(str(paths.get_logs_dir() / "log_registry.toml"))
|
||||
pruner = log_pruner.LogPruner(registry, str(paths.get_logs_dir()))
|
||||
pruner.prune()
|
||||
except Exception as e:
|
||||
return OK
|
||||
except (OSError, IOError, ValueError, TypeError, AttributeError) as e:
|
||||
logging.getLogger(__name__).debug("log pruning error: %s", e, extra={"source": "app_controller._prune_old_logs.run_prune"})
|
||||
print(f"Error during log pruning: {e}")
|
||||
return Result(data=None, errors=[ErrorInfo(
|
||||
kind=ErrorKind.INTERNAL,
|
||||
message=str(e),
|
||||
source="app_controller._prune_old_logs.run_prune",
|
||||
original=e,
|
||||
)])
|
||||
self.submit_io(run_prune)
|
||||
|
||||
def start_services(self, app: Any = None):
|
||||
@@ -2915,7 +2933,8 @@ class AppController:
|
||||
tickets=tickets
|
||||
)
|
||||
self.active_tickets = at_data.get("tickets", []) # Keep dicts for UI table
|
||||
except Exception as e:
|
||||
except (TypeError, ValueError, KeyError, AttributeError) as e:
|
||||
logging.getLogger(__name__).debug("active track deserialize failed: %s", e, extra={"source": "app_controller._refresh_from_project.active_track"})
|
||||
print(f"Failed to deserialize active track: {e}")
|
||||
self.active_track = None
|
||||
else:
|
||||
@@ -2969,7 +2988,8 @@ class AppController:
|
||||
try:
|
||||
cleaned = project_manager.clean_nones(self.project)
|
||||
project_manager.save_project(cleaned, self.active_project_path)
|
||||
except Exception as e:
|
||||
except (OSError, IOError, ValueError, TypeError, KeyError, AttributeError) as e:
|
||||
logging.getLogger(__name__).debug("save_project failed: %s", e, extra={"source": "app_controller._save_active_project"})
|
||||
self.ai_status = f"save error: {e}"
|
||||
|
||||
#endregion: Project
|
||||
|
||||
Reference in New Issue
Block a user