TIER-2 READ conductor/code_styleguides/error_handling.md end-to-end before Phase 10: refactor(gui_2): migrate L216 _detect_refresh_rate_win32 to Result[T] (Phase 10 site 1)

Extracted _detect_refresh_rate_win32_result() helper above the legacy wrapper.
ANTI-SLIMING: full Result[T] propagation (NO narrowing+logging). The helper
returns Result(data=rate) on success or Result(data=0.0, errors=[ErrorInfo])
on exception (logging NOT a drain per the user's principle 2026-06-17).

The legacy _detect_refresh_rate_win32() wrapper preserves its signature and
delegates to the helper. The call site in App.__init__ invokes the result
helper directly and drains errors to self._startup_timeline_errors.

Tests: 2 new tests (test_phase_10_l216_detect_refresh_rate_win32_result_success,
test_phase_10_l216_detect_refresh_rate_win32_result_failure) verify both paths.

Audit: L216 reclassified from INTERNAL_SILENT_SWALLOW (12 sites remaining,
was 13). New helper L219 is INTERNAL_COMPLIANT.
This commit is contained in:
ed
2026-06-20 00:42:06 -04:00
parent 11d331238d
commit c73038382e
12 changed files with 219 additions and 11 deletions
+54
View File
@@ -1722,3 +1722,57 @@ def test_phase_9_invariant_zero_sites_in_phase_9():
f"inventory and migrate it."
)
# =============================================================================
# Phase 10 Tests - INTERNAL_SILENT_SWALLOW migrations
# Per conductor/code_styleguides/error_handling.md lines 462-540:
# "Logging is NOT a drain point." The 13 sites in this phase have logging-only
# except bodies (sys.stderr.write, print, traceback.print_exc, pass). They
# MUST be migrated to full Result[T] propagation. NOT narrowing + logging.
# NOT pass-after-logging. NOT "intentional silent recovery".
# =============================================================================
def test_phase_10_l216_detect_refresh_rate_win32_result_success():
"""
L216 _detect_refresh_rate_win32_result returns Result(data=float) on success.
The helper extracts the try/except body from _detect_refresh_rate_win32
into a Result-returning helper. On success (when EnumDisplaySettingsW
returns a valid dmDisplayFrequency > 1), the helper returns
Result(data=rate).
"""
from unittest.mock import patch
import src.gui_2 as gui2_mod
def fake_eds(_devname, _mode, byref_dm):
real_dm = byref_dm._obj
real_dm.dmDisplayFrequency = 144
return 1
with patch("ctypes.windll.user32.EnumDisplaySettingsW", side_effect=fake_eds):
result = gui2_mod._detect_refresh_rate_win32_result()
assert result.ok, f"Expected ok=True on success, got errors: {result.errors}"
assert result.data == 144.0
def test_phase_10_l216_detect_refresh_rate_win32_result_failure():
"""
L216 _detect_refresh_rate_win32_result returns Result(data=0.0, errors=[ErrorInfo]) on failure.
When the ctypes windll call raises (e.g., on a non-Windows system or
when user32 is unavailable), the helper returns Result(data=0.0)
with ErrorInfo describing the failure. The original function returned
0.0 on error (preserved as the safe fallback in the legacy wrapper).
"""
from unittest.mock import patch
import src.gui_2 as gui2_mod
with patch("ctypes.windll.user32.EnumDisplaySettingsW", side_effect=OSError("user32 unavailable")):
result = gui2_mod._detect_refresh_rate_win32_result()
assert not result.ok, f"Expected ok=False on failure, got data: {result.data}"
assert result.data == 0.0
assert result.errors, "Expected at least one error on failure"
err = result.errors[0]
assert err.source == "gui_2._detect_refresh_rate_win32_result"
assert "user32 unavailable" in err.message