From d9f6b110bc8ce9615258adf691da36df1b5ff319 Mon Sep 17 00:00:00 2001 From: ChuckBuilds Date: Sat, 5 Sep 2026 17:25:24 -0400 Subject: [PATCH] refactor: narrow the exception handlers this branch introduced Codacy flagged the new code; it passes on other recent PRs, so the finding is mine. Four of the five broad `except Exception` clauses I added were catching far more than they needed to, which is the same shape as several bugs this branch fixes -- hello-world's TypeError sat invisible for exactly this reason. freezer() / move_to() / tick() -> (AttributeError, TypeError, ValueError) cache_manager.delete() -> (OSError, AttributeError, KeyError) The fifth stays broad and now says why: it wraps a call into a plugin's own display(), which can raise anything, and the first frame has already rendered -- so a failure there must not turn a good result into an error. Verified against a checkout of main: f1-scoreboard 48 PASS / 0 FAIL with 0 empty warnings, on-air keeps its 8 true positives, clock-simple 8 PASS. geochron shows 7 golden drifts both before and after this branch, so it is not from these changes -- its committed goldens predate #521's 1-bit text rendering. --- src/display_controller.py | 4 +++- src/plugin_system/testing/harness.py | 16 ++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/display_controller.py b/src/display_controller.py index 72100568..5acb7b11 100644 --- a/src/display_controller.py +++ b/src/display_controller.py @@ -1333,7 +1333,9 @@ class DisplayController: # against double-processing if this delete fails. try: self.cache_manager.delete('display_on_demand_request') - except Exception as err: # pragma: no cover - best-effort cleanup + except (OSError, AttributeError, KeyError) as err: + # Best-effort: processed_id still guards against reprocessing if the + # mailbox cannot be cleared. logger.debug("Could not clear the on-demand request mailbox: %s", err) if action == 'start': diff --git a/src/plugin_system/testing/harness.py b/src/plugin_system/testing/harness.py index d46c11c7..628e13ce 100644 --- a/src/plugin_system/testing/harness.py +++ b/src/plugin_system/testing/harness.py @@ -222,7 +222,9 @@ def _settle_empty_frame(inst, mode, dm, result, freezer) -> None: if freezer is not None: try: resume_at = freezer() - except Exception: # noqa: BLE001 - only to restore, never load-bearing + except (AttributeError, TypeError, ValueError): + # Not a freezegun factory, or a version whose factory is not + # callable. Only used to restore the clock, never load-bearing. resume_at = None try: _settle_loop(inst, mode, dm, result, freezer) @@ -230,7 +232,7 @@ def _settle_empty_frame(inst, mode, dm, result, freezer) -> None: if resume_at is not None: try: freezer.move_to(resume_at) - except Exception: # noqa: BLE001 + except (AttributeError, TypeError, ValueError): pass @@ -242,7 +244,9 @@ def _settle_loop(inst, mode, dm, result, freezer) -> None: # number only since 1.x, and a stale pin would raise here. try: tick(timedelta(seconds=EMPTY_RECHECK_STEP)) - except Exception: # noqa: BLE001 - pacing is best-effort + except (AttributeError, TypeError, ValueError): + # Pacing is best-effort; a freezegun that will not take a + # timedelta just means this probe runs without advancing time. pass else: # No frozen clock, so the real one has to do the advancing. Without @@ -252,7 +256,11 @@ def _settle_loop(inst, mode, dm, result, freezer) -> None: time.sleep(EMPTY_RECHECK_STEP) try: result.display_returned = _render_mode_again(inst, mode) - except Exception: # noqa: BLE001 - the first frame already succeeded + except Exception: # noqa: BLE001 + # Deliberately broad: this calls a plugin's display(), which can + # raise anything. The first frame already rendered, so whatever + # happens on a re-draw must not turn a good result into an error -- + # keep the frame we have and stop probing. return image = dm.get_image() if _has_content(image):