From bcbd46445f14c249b607629ab7ca6e238e13a1ea Mon Sep 17 00:00:00 2001 From: Ed_ Date: Fri, 19 Jun 2026 22:07:51 -0400 Subject: [PATCH] refactor(gui_2): migrate L1171 _show_menus do_generate to Result[T] (Phase 3) TIER-2 READ conductor/code_styleguides/error_handling.md end-to-end before Phase 3. Adds _show_menus_do_generate_result(app) -> Result[bool] helper that wraps the 'Generate MD Only' menu handler try/except in App._show_menus. The legacy if-branch in App._show_menus becomes a thin call that drains errors to _last_request_errors. Audit: BROAD_CATCH count 22 -> 21, COMPLIANT count 15 -> 16. Tests: 2/2 pass. --- src/gui_2.py | 36 ++++++++++++++++++++++++------ tests/test_gui_2_result.py | 45 +++++++++++++++++++++++++++++++++++++- 2 files changed, 73 insertions(+), 8 deletions(-) diff --git a/src/gui_2.py b/src/gui_2.py index b2e9517d..0a537782 100644 --- a/src/gui_2.py +++ b/src/gui_2.py @@ -1163,13 +1163,10 @@ class App: self.ai_status = "session reset" self.ai_response = "" if imgui.menu_item("Generate MD Only", "", False)[0]: - try: - md, path, *_ = self._do_generate() - self.last_md = md - self.last_md_path = path - self.ai_status = f"md written: {path.name}" - except Exception as e: - self.ai_status = f"error: {e}" + result = _show_menus_do_generate_result(self) + if not result.ok: + if not hasattr(self, '_last_request_errors'): self._last_request_errors = [] + self._last_request_errors.append(("_show_menus.do_generate", result.errors[0])) with imscope.menu("Layout") as (active): if active: if imgui.menu_item("Save Current...", "", False)[0]: @@ -7506,6 +7503,31 @@ def _render_main_interface_result(app: "App") -> Result[bool]: original=e, )]) +def _show_menus_do_generate_result(app: "App") -> Result[bool]: + """Drain-aware variant of L1171 _show_menus 'Generate MD Only' menu handler. + + Extracts the try/except from the "Generate MD Only" if-branch in + App._show_menus into a Result-returning helper. On success, sets + app.last_md, app.last_md_path, app.ai_status. On failure, sets + app.ai_status to an error message. + + [C: src/gui_2.py:App._show_menus (L1171 legacy wrapper)] + """ + try: + md, path, *_ = app._do_generate() + app.last_md = md + app.last_md_path = path + app.ai_status = f"md written: {path.name}" + return Result(data=True) + except Exception as e: + app.ai_status = f"error: {e}" + return Result(data=False, errors=[ErrorInfo( + kind=ErrorKind.INTERNAL, + message=f"Generate MD Only failed: {e}", + source="gui_2._show_menus_do_generate_result", + original=e, + )]) + #endregion: Phase 3 Render-Loop Result Helpers #endregion: MMA diff --git a/tests/test_gui_2_result.py b/tests/test_gui_2_result.py index 23302bcd..eec0a43f 100644 --- a/tests/test_gui_2_result.py +++ b/tests/test_gui_2_result.py @@ -335,4 +335,47 @@ def test_phase_3_l1123_render_main_interface_result_failure(): assert result.errors, "Expected at least one error on failure" err = result.errors[0] assert err.source == "gui_2._render_main_interface_result" - assert "render blew up" in err.message \ No newline at end of file + assert "render blew up" in err.message + + +def test_phase_3_l1171_show_menus_do_generate_result_success(): + """ + L1171 _show_menus_do_generate_result returns Result.ok=True on success. + + The helper wraps the "Generate MD Only" try/except in App._show_menus. + On success, sets app.last_md, app.last_md_path, app.ai_status and + returns Result(data=True). + """ + from src import gui_2 + from unittest.mock import MagicMock + app = MagicMock() + mock_md = MagicMock(name="mock_md") + mock_path = MagicMock(name="mock_path") + mock_path.name = "out.md" + app._do_generate.return_value = (mock_md, mock_path) + result = gui_2._show_menus_do_generate_result(app) + assert result.ok, f"Expected ok=True on success, got errors: {result.errors}" + assert result.data is True + assert app.last_md is mock_md + assert app.last_md_path is mock_path + assert "md written" in app.ai_status + + +def test_phase_3_l1171_show_menus_do_generate_result_failure(): + """ + L1171 _show_menus_do_generate_result returns Result.ok=False on failure. + + When _do_generate raises, the helper sets app.ai_status to an error + message and returns Result(data=False, errors=[ErrorInfo]). + """ + from src import gui_2 + from unittest.mock import MagicMock + app = MagicMock() + app._do_generate.side_effect = RuntimeError("generate blew up") + result = gui_2._show_menus_do_generate_result(app) + assert not result.ok, f"Expected ok=False on failure, got data: {result.data}" + assert result.errors, "Expected at least one error on failure" + err = result.errors[0] + assert err.source == "gui_2._show_menus_do_generate_result" + assert "generate blew up" in err.message + assert "error" in app.ai_status \ No newline at end of file