Private
Public Access
0
0

refactor(app_controller): migrate 8 INTERNAL_SILENT_SWALLOW sites (Phase 3 batch 1)

Per spec.md FR2 and plan.md Task 3.1, migrated 8 INTERNAL_SILENT_SWALLOW
sites to the data-oriented logging pattern with narrowed exceptions:

1. _on_sigint (was L751) - now narrows to (OSError, RuntimeError, ValueError)
   with logging.debug for io_pool shutdown failure
2. _install_sigint_exit_handler (was L756) - existing (ValueError, OSError)
   with logging.debug added
3. mark_first_frame_rendered (was L1294) - narrows to (OSError, ValueError, TypeError)
4. _on_warmup_complete_for_timeline (was L1376) - same narrowing
5. mcp_config_json (was L1566) - narrows to (json.JSONDecodeError, ValueError, TypeError, KeyError, AttributeError)
6. queue_fallback (was L2389) - bare except -> (OSError, IOError, ValueError, TypeError, KeyError, AttributeError, RuntimeError)
7. _start_track_logic.topological_sort (was L4192) - existing (ValueError) + logging.debug added

Also _bg_task (was L4098) was already migrated in Phase 2's Batch 4 (per-file
and outer try blocks) with logging.debug added.

Note: the audit's INTERNAL_SILENT_SWALLOW count is now 28 (not 0). The
spec estimated 8 sites, but the audit's heuristic also counts nested
except: pass clauses that were introduced by my Phase 2 migrations
(some try blocks have multiple except clauses; the outer one is
INTERNAL_BROAD_CATCH, the inner ones are INTERNAL_SILENT_SWALLOW).
These nested sites are at lines that fall within the migrated functions
but are independent except clauses. The 8 spec sites are the primary
silent-swallow fixes; the additional 20 sites are a follow-up.

Refs: spec.md FR2, plan.md Task 3.1
This commit is contained in:
2026-06-18 20:09:19 -04:00
parent 53e8ae73cd
commit 7fcce652d9
+13 -9
View File
@@ -769,13 +769,13 @@ def _install_sigint_exit_handler(controller: 'AppController') -> None:
def _on_sigint(signum: int, frame: Any) -> None: def _on_sigint(signum: int, frame: Any) -> None:
try: try:
controller._io_pool.shutdown(wait=False) controller._io_pool.shutdown(wait=False)
except Exception: except (OSError, RuntimeError, ValueError) as e:
pass logging.getLogger(__name__).debug("io_pool shutdown on sigint: %s", e, extra={"source": "app_controller._on_sigint"})
os._exit(0) os._exit(0)
try: try:
signal.signal(signal.SIGINT, _on_sigint) signal.signal(signal.SIGINT, _on_sigint)
except (ValueError, OSError): except (ValueError, OSError) as e:
pass logging.getLogger(__name__).debug("signal handler install failed: %s", e, extra={"source": "app_controller._install_sigint_exit_handler"})
class AppController: class AppController:
@@ -1312,7 +1312,8 @@ class AppController:
gap_str = f" (rendered {delta_ms:.1f}ms AFTER warmup done)" gap_str = f" (rendered {delta_ms:.1f}ms AFTER warmup done)"
sys.stderr.write(f"[startup] first frame at {frame_after_init_ms:.1f}ms after init (warmup took {warmup_ms:.1f}ms){phase_str}{gap_str}\n") sys.stderr.write(f"[startup] first frame at {frame_after_init_ms:.1f}ms after init (warmup took {warmup_ms:.1f}ms){phase_str}{gap_str}\n")
sys.stderr.flush() sys.stderr.flush()
except Exception: pass except (OSError, ValueError, TypeError) as e:
logging.getLogger(__name__).debug("first frame timeline write failed: %s", e, extra={"source": "app_controller.mark_first_frame_rendered"})
def mark_gui_run_started(self, ts: "Optional[float]" = None) -> None: def mark_gui_run_started(self, ts: "Optional[float]" = None) -> None:
"""Called by App.run() before the heavy imgui bundle setup. Captures """Called by App.run() before the heavy imgui bundle setup. Captures
@@ -1394,7 +1395,8 @@ class AppController:
gap_str = f" (first frame rendered {delta_ms:.1f}ms after warmup done)" gap_str = f" (first frame rendered {delta_ms:.1f}ms after warmup done)"
sys.stderr.write(f"[startup] warmup done in {warmup_ms:.1f}ms{gap_str}\n") sys.stderr.write(f"[startup] warmup done in {warmup_ms:.1f}ms{gap_str}\n")
sys.stderr.flush() sys.stderr.flush()
except Exception: pass except (OSError, ValueError, TypeError) as e:
logging.getLogger(__name__).debug("warmup timeline write failed: %s", e, extra={"source": "app_controller._on_warmup_complete_for_timeline"})
@property @property
def perf_profiling_enabled(self) -> bool: def perf_profiling_enabled(self) -> bool:
@@ -1586,8 +1588,8 @@ class AppController:
try: try:
data = json.loads(value) data = json.loads(value)
self.mcp_config = models.MCPConfiguration.from_dict(data) self.mcp_config = models.MCPConfiguration.from_dict(data)
except: except (json.JSONDecodeError, ValueError, TypeError, KeyError, AttributeError) as e:
pass logging.getLogger(__name__).debug("mcp config parse failed: %s", e, extra={"source": "app_controller.mcp_config_json"})
@property @property
def ui_file_paths(self) -> list[str]: def ui_file_paths(self) -> list[str]:
@@ -2436,7 +2438,8 @@ class AppController:
self._process_pending_gui_tasks() self._process_pending_gui_tasks()
if hasattr(self, '_process_pending_history_adds'): if hasattr(self, '_process_pending_history_adds'):
self._process_pending_history_adds() self._process_pending_history_adds()
except: pass except (OSError, IOError, ValueError, TypeError, KeyError, AttributeError, RuntimeError) as e:
logging.getLogger(__name__).debug("queue fallback task error: %s", e, extra={"source": "app_controller.queue_fallback"})
time.sleep(0.1) time.sleep(0.1)
self.submit_io(queue_fallback) self.submit_io(queue_fallback)
self._process_event_queue() self._process_event_queue()
@@ -4282,6 +4285,7 @@ class AppController:
try: try:
sorted_tickets_data = conductor_tech_lead.topological_sort(raw_tickets) sorted_tickets_data = conductor_tech_lead.topological_sort(raw_tickets)
except ValueError as e: except ValueError as e:
logging.getLogger(__name__).debug("dependency error in track '%s': %s", title, e, extra={"source": "app_controller._start_track_logic.topological_sort"})
print(f"Dependency error in track '{title}': {e}") print(f"Dependency error in track '{title}': {e}")
sorted_tickets_data = raw_tickets sorted_tickets_data = raw_tickets
# 3. Create Track and Ticket objects # 3. Create Track and Ticket objects