refactor(app_controller): migrate _cb_run_conductor_setup + _cb_load_track to Result (Phase 6 Groups 6.5+6.7 partial)
Migrates the 2 remaining _cb_* sites with proper Result[T] propagation: - _cb_run_conductor_setup: per-file read via _read_conductor_file_result - _cb_load_track: state hydration via _cb_load_track_result New helpers: - _read_conductor_file_result(f) -> Result[int] - _cb_load_track_result(state, track_id) -> Result[None] Audit: INTERNAL_SILENT_SWALLOW for src/app_controller.py: 12 -> 10.
This commit is contained in:
+64
-34
@@ -4749,6 +4749,22 @@ class AppController:
|
||||
engine.engine = ExecutionEngine(engine.dag, auto_queue=engine.engine.auto_queue)
|
||||
self._push_mma_state_update()
|
||||
|
||||
def _read_conductor_file_result(self, f: Path) -> "Result[int]":
|
||||
"""Phase 6 Group 6.7: read a conductor file and return line count.
|
||||
On failure: OSError/IOError/UnicodeDecodeError -> ErrorInfo(original=e).
|
||||
Caller (`_cb_run_conductor_setup`) records per-file errors and
|
||||
adds an 'Error reading' line to the summary."""
|
||||
try:
|
||||
with open(f, "r", encoding="utf-8") as fd:
|
||||
return Result(data=len(fd.readlines()))
|
||||
except (OSError, IOError, UnicodeDecodeError) as e:
|
||||
return Result(data=0, errors=[ErrorInfo(
|
||||
kind=ErrorKind.INTERNAL,
|
||||
message=str(e),
|
||||
source=f"app_controller._read_conductor_file_result[{f.name}]",
|
||||
original=e,
|
||||
)])
|
||||
|
||||
def _cb_run_conductor_setup(self) -> None:
|
||||
"""
|
||||
[C: src/gui_2.py:App._render_mma_conductor_setup, tests/test_gui_phase3.py:test_conductor_setup_scan]
|
||||
@@ -4763,13 +4779,12 @@ class AppController:
|
||||
summary.append(f"Total Files: {len(files)}")
|
||||
total_lines = 0
|
||||
for f in files:
|
||||
try:
|
||||
with open(f, "r", encoding="utf-8") as fd:
|
||||
lines = len(fd.readlines())
|
||||
total_lines += lines
|
||||
summary.append(f"- {f.relative_to(base)}: {lines} lines")
|
||||
except (OSError, IOError, UnicodeDecodeError) as e:
|
||||
logging.getLogger(__name__).debug("conductor file read failed for %s: %s", f, e, extra={"source": "app_controller._cb_run_conductor_setup"})
|
||||
result = self._read_conductor_file_result(f)
|
||||
if result.ok:
|
||||
total_lines += result.data
|
||||
summary.append(f"- {f.relative_to(base)}: {result.data} lines")
|
||||
else:
|
||||
self._last_request_errors.append((f"conductor_file_read[{f.name}]", result.errors[0]))
|
||||
summary.append(f"- {f.relative_to(base)}: Error reading")
|
||||
summary.append(f"Total Line Count: {total_lines}")
|
||||
tracks_dir = base / "tracks"
|
||||
@@ -4842,34 +4857,49 @@ class AppController:
|
||||
"""
|
||||
state = project_manager.load_track_state(track_id, self.active_project_root)
|
||||
if state:
|
||||
try:
|
||||
result = self._cb_load_track_result(state, track_id)
|
||||
if not result.ok:
|
||||
err = result.errors[0]
|
||||
self.ai_status = f"Load track error: {err.message}"
|
||||
print(f"Error loading track {track_id}: {err.message}")
|
||||
self._report_worker_error("cb_load_track", result)
|
||||
|
||||
def _cb_load_track_result(self, state, track_id: str) -> "Result[None]":
|
||||
"""Phase 6 Group 6.7: load a track with Result propagation.
|
||||
On failure: OSError/IOError/ValueError/TypeError/KeyError/AttributeError/tomllib.TOMLDecodeError
|
||||
-> ErrorInfo(original=e). Caller drains via stderr print + ai_status."""
|
||||
try:
|
||||
# Convert list[Ticket] or list[dict] to list[Ticket] for Track object
|
||||
tickets = []
|
||||
for t in state.tasks:
|
||||
if isinstance(t, dict):
|
||||
tickets.append(models.Ticket(**t))
|
||||
else:
|
||||
tickets.append(t)
|
||||
self.active_track = models.Track(
|
||||
id=state.metadata.id,
|
||||
description=state.metadata.name,
|
||||
tickets=tickets
|
||||
)
|
||||
# Keep dicts for UI table
|
||||
self._load_active_tickets()
|
||||
# Load track-scoped history
|
||||
history = project_manager.load_track_history(track_id, self.active_project_root)
|
||||
with self._disc_entries_lock:
|
||||
if history:
|
||||
self.disc_entries[:] = models.parse_history_entries(history, self.disc_roles)
|
||||
else:
|
||||
self.disc_entries.clear()
|
||||
self._recalculate_session_usage()
|
||||
self.ai_status = f"Loaded track: {state.metadata.name}"
|
||||
except (OSError, IOError, ValueError, TypeError, KeyError, AttributeError, tomllib.TOMLDecodeError) as e:
|
||||
logging.getLogger(__name__).debug("load track failed: %s", e, extra={"source": "app_controller._cb_load_track"})
|
||||
self.ai_status = f"Load track error: {e}"
|
||||
print(f"Error loading track {track_id}: {e}")
|
||||
tickets = []
|
||||
for t in state.tasks:
|
||||
if isinstance(t, dict):
|
||||
tickets.append(models.Ticket(**t))
|
||||
else:
|
||||
tickets.append(t)
|
||||
self.active_track = models.Track(
|
||||
id=state.metadata.id,
|
||||
description=state.metadata.name,
|
||||
tickets=tickets
|
||||
)
|
||||
# Keep dicts for UI table
|
||||
self._load_active_tickets()
|
||||
# Load track-scoped history
|
||||
history = project_manager.load_track_history(track_id, self.active_project_root)
|
||||
with self._disc_entries_lock:
|
||||
if history:
|
||||
self.disc_entries[:] = models.parse_history_entries(history, self.disc_roles)
|
||||
else:
|
||||
self.disc_entries.clear()
|
||||
self._recalculate_session_usage()
|
||||
self.ai_status = f"Loaded track: {state.metadata.name}"
|
||||
return OK
|
||||
except (OSError, IOError, ValueError, TypeError, KeyError, AttributeError, tomllib.TOMLDecodeError) as e:
|
||||
return Result(data=None, errors=[ErrorInfo(
|
||||
kind=ErrorKind.INTERNAL,
|
||||
message=str(e),
|
||||
source="app_controller._cb_load_track_result",
|
||||
original=e,
|
||||
)])
|
||||
|
||||
def _push_mma_state_update(self) -> None:
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user