Skip to content

fix(tui): narrow bare except clauses to specific exceptions - #154

Merged
Q00 merged 1 commit into
Q00:mainfrom
lifrary:fix/tui-narrow-bare-except
Mar 17, 2026
Merged

Q00 merged 1 commit into
Q00:mainfrom
lifrary:fix/tui-narrow-bare-except

Conversation

@lifrary

@lifrary lifrary commented Mar 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Replace 30 overly broad except Exception: pass with precise exception types across 11 TUI files.

  • 29× except NoMatches: for query_one() calls that may fail when widgets are not yet mounted or have been removed from the DOM
  • 1× except ValueError: for datetime.fromisoformat() parsing in event_log.py

Why this matters

Bare except Exception silently swallows real bugs — TypeError, KeyError, AttributeError all get hidden behind pass. This makes debugging TUI issues unnecessarily difficult, since genuine errors disappear without a trace.

query_one() only raises NoMatches when the CSS selector finds no widget. The other exception it can raise — TooManyMatches — is intentionally not caught, because duplicate widget IDs indicate a real bug that should surface immediately.

Files changed

Components (4 files, 13 changes):

  • agents_panel.py — 1× NoMatches (DataTable query)
  • event_log.py — 3× NoMatches + 1× ValueError (datetime parsing)
  • progress.py — 5× NoMatches (progress display updates)
  • token_tracker.py — 3× NoMatches (summary/tier/budget widgets)

Screens (5 files, 15 changes):

  • dashboard.py — 3× NoMatches (status widgets)
  • dashboard_v2.py — 7× NoMatches (mini-status widgets)
  • dashboard_v3.py — 2× NoMatches (Tree widget)
  • hud_dashboard.py — 2× NoMatches (HUD row / Tree widget)
  • logs.py — 1× NoMatches (VerticalScroll container)

Widgets (2 files, 2 changes):

  • agent_activity.py — 1× NoMatches (activity display)
  • lineage_tree.py — 1× NoMatches (Tree widget)

What was intentionally left unchanged

  • app.py (11 instances) — wraps polling, file I/O, and state updates, not query_one()
  • screens/debug.py (2 instances) — uses except Exception as e: with logging; intentional broad catch
  • screens/lineage_detail.py (5 instances) — mixed patterns including git operations and as e logging
  • screens/session_selector.py, lineage_selector.py — as e patterns with error handling

These require case-by-case analysis and are better suited for a follow-up PR.

Test plan

  • ruff check — all checks passed (no lint issues)
  • pytest tests/ — 2516 passed
  • Full grep -rn "except Exception" src/ouroboros/tui/ audit — all remaining instances verified as intentional

🤖 Generated with Claude Code

Replace 30 overly broad `except Exception: pass` with precise exception
types across 11 TUI files:

- 29× `except NoMatches:` for `query_one()` calls that may fail when
  widgets are not yet mounted or have been removed from the DOM
- 1× `except ValueError:` for `datetime.fromisoformat()` parsing

Bare `except Exception` silently swallows real bugs (TypeError,
KeyError, AttributeError) that should surface during development.
`query_one()` only raises `NoMatches` when the selector finds no
widget — `TooManyMatches` is intentionally not caught since duplicate
widget IDs indicate a real bug that should be fixed.

Files changed:
- components/: agents_panel, event_log, progress, token_tracker
- screens/: dashboard, dashboard_v2, dashboard_v3, hud_dashboard, logs
- widgets/: agent_activity, lineage_tree

Co-Authored-By: Claude Opus 4.6 <[email protected]>

@ouroboros-agent ouroboros-agent Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Updated to APPROVE review below)

@ouroboros-agent ouroboros-agent Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review — ouroboros-agent[bot]

Verdict: APPROVE

Branch: fix/tui-narrow-bare-except | 11 files, +41/-30 | CI: all required checks passing

Issue #N Requirements

Requirement Status
Narrow broad except Exception handlers around query_one() calls to the specific missing-widget failure mode MET — all 29 UI lookup sites now import and catch NoMatches instead of swallowing unrelated exceptions (src/ouroboros/tui/components/progress.py:302, src/ouroboros/tui/screens/dashboard_v2.py:488, src/ouroboros/tui/widgets/lineage_tree.py:135)
Preserve fallback behavior for malformed event-log timestamps while exposing unrelated runtime bugs MET — event_log.py now falls back only on ValueError from datetime.fromisoformat(...) instead of masking arbitrary exceptions (src/ouroboros/tui/components/event_log.py:347)

Code Findings

# File:Line Severity Confidence Finding
1 N/A Low 95% No blocking issues found. The change consistently narrows exception handling to the expected failure mode and intentionally leaves TooManyMatches visible, which is the right tradeoff for surfacing real TUI bugs.

Test Coverage

  • CI is green across Ruff, MyPy, and Python 3.12/3.13/3.14 test jobs.
  • The PR description documents a full pytest tests/ pass and a repo-wide audit of remaining except Exception usage.
  • I did not see a targeted regression test for the missing-widget paths, but this is acceptable here because the change is a mechanical exception narrowing with broad existing suite coverage.

Design

  • Good cleanup: it reduces silent failure scope without changing the intended UI fallback behavior.

ouroboros-agent[bot]

@Q00
Q00 merged commit 1fd006b into Q00:main Mar 17, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants