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.
This commit is contained in:
+29
-7
@@ -1163,13 +1163,10 @@ class App:
|
|||||||
self.ai_status = "session reset"
|
self.ai_status = "session reset"
|
||||||
self.ai_response = ""
|
self.ai_response = ""
|
||||||
if imgui.menu_item("Generate MD Only", "", False)[0]:
|
if imgui.menu_item("Generate MD Only", "", False)[0]:
|
||||||
try:
|
result = _show_menus_do_generate_result(self)
|
||||||
md, path, *_ = self._do_generate()
|
if not result.ok:
|
||||||
self.last_md = md
|
if not hasattr(self, '_last_request_errors'): self._last_request_errors = []
|
||||||
self.last_md_path = path
|
self._last_request_errors.append(("_show_menus.do_generate", result.errors[0]))
|
||||||
self.ai_status = f"md written: {path.name}"
|
|
||||||
except Exception as e:
|
|
||||||
self.ai_status = f"error: {e}"
|
|
||||||
with imscope.menu("Layout") as (active):
|
with imscope.menu("Layout") as (active):
|
||||||
if active:
|
if active:
|
||||||
if imgui.menu_item("Save Current...", "", False)[0]:
|
if imgui.menu_item("Save Current...", "", False)[0]:
|
||||||
@@ -7506,6 +7503,31 @@ def _render_main_interface_result(app: "App") -> Result[bool]:
|
|||||||
original=e,
|
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: Phase 3 Render-Loop Result Helpers
|
||||||
|
|
||||||
#endregion: MMA
|
#endregion: MMA
|
||||||
|
|||||||
@@ -336,3 +336,46 @@ def test_phase_3_l1123_render_main_interface_result_failure():
|
|||||||
err = result.errors[0]
|
err = result.errors[0]
|
||||||
assert err.source == "gui_2._render_main_interface_result"
|
assert err.source == "gui_2._render_main_interface_result"
|
||||||
assert "render blew up" in err.message
|
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
|
||||||
Reference in New Issue
Block a user