mirror of
https://github.com/github/spec-kit.git
synced 2026-08-15 14:02:04 +02:00
fix: log progress tracker refresh errors instead of silently swallowing (#3975)
* fix: log progress tracker refresh errors instead of silently swallowing The bare 'except Exception: pass' in StepTracker._maybe_refresh() completely hid rendering bugs in the Rich progress display. Now logs at DEBUG level with full traceback for diagnostics. * test: add regression test for StepTracker refresh error logging - Test that _maybe_refresh logs exceptions instead of silently swallowing - Verify diagnostic message and traceback are recorded in DEBUG logs - Confirm tracker update completes normally despite refresh callback failure Requested by Copilot in PR #3975
This commit is contained in:
@@ -7,6 +7,7 @@ layer, not out of it, to avoid circular imports.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import sys
|
||||
from collections.abc import Callable
|
||||
|
||||
@@ -21,6 +22,8 @@ from rich.text import Text
|
||||
from rich.tree import Tree
|
||||
from typer.core import TyperGroup
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
BANNER = """
|
||||
███████╗██████╗ ███████╗ ██████╗██╗███████╗██╗ ██╗
|
||||
██╔════╝██╔══██╗██╔════╝██╔════╝██║██╔════╝╚██╗ ██╔╝
|
||||
@@ -85,7 +88,7 @@ class StepTracker:
|
||||
try:
|
||||
self._refresh_cb()
|
||||
except Exception:
|
||||
pass
|
||||
logger.debug("Progress tracker refresh failed", exc_info=True)
|
||||
|
||||
def render(self):
|
||||
tree = Tree(f"[cyan]{self.title}[/cyan]", guide_style="grey50")
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
"""Regression guard: console symbols must remain importable from specify_cli."""
|
||||
import logging
|
||||
|
||||
from specify_cli import (
|
||||
console,
|
||||
StepTracker,
|
||||
select_with_arrows,
|
||||
)
|
||||
from specify_cli._console import logger as console_logger
|
||||
|
||||
|
||||
def test_console_symbols_importable():
|
||||
@@ -39,3 +42,21 @@ def test_select_with_arrows_raises_on_empty_options():
|
||||
import pytest
|
||||
with pytest.raises(ValueError, match="at least one option"):
|
||||
select_with_arrows({})
|
||||
|
||||
|
||||
def test_step_tracker_refresh_error_is_logged(caplog):
|
||||
"""Regression: _maybe_refresh must log exceptions instead of silently swallowing."""
|
||||
tracker = StepTracker("test")
|
||||
|
||||
def failing_refresh():
|
||||
raise RuntimeError("simulated refresh failure")
|
||||
|
||||
tracker.attach_refresh(failing_refresh)
|
||||
tracker.add("step1", "Step One")
|
||||
|
||||
with caplog.at_level(logging.DEBUG, logger=console_logger.name):
|
||||
tracker.complete("step1", "done")
|
||||
|
||||
assert "Progress tracker refresh failed" in caplog.text
|
||||
assert "RuntimeError: simulated refresh failure" in caplog.text
|
||||
assert tracker.steps[0]["status"] == "done"
|
||||
|
||||
Reference in New Issue
Block a user