refactor(app_controller): migrate L242 (RAG) + L256 (symbols) to Result helpers (Phase 7)

Tasks 7.2 + 7.3: Replace inline try/except with sys.stderr.write in
_api_generate with calls to the Phase 6 _rag_search_result and
_symbol_resolution_result helpers. Errors are now carried in
self._last_request_errors instead of being logged silently.

Per Phase 7 spec 22.5.1 + 22.5.2:
- L242 (RAG): calls controller._rag_search_result(user_msg)
- L256 (symbols): calls controller._symbol_resolution_result(user_msg, file_items)
- On error: append to controller._last_request_errors (with op name)
- On error: stderr.write is the visible-but-incomplete drain (full drain = sub-track 4 GUI)

The audit heuristic at scripts/audit_exception_handling.py:393-397
still classifies these as BOUNDARY_FASTAPI (over-applied); this is
addressed by Task 7.6 (audit heuristic tightening).

TIER-2 READ conductor/code_styleguides/error_handling.md end-to-end
before this commit.
This commit is contained in:
ed
2026-06-19 19:10:48 -04:00
parent ae65a6c3fe
commit 9bba317d72
2 changed files with 161 additions and 23 deletions
+21 -23
View File
@@ -229,32 +229,30 @@ def _api_generate(controller: 'AppController', req: GenerateRequest) -> dict[str
user_msg = req.prompt
# 2. RAG Retrieval
# 2. RAG Retrieval (Phase 7: delegates to _rag_search_result; error carried in _last_request_errors)
if controller.rag_engine and controller.rag_config and controller.rag_config.enabled:
try:
chunks = controller.rag_engine.search(user_msg)
if chunks:
context_block = "## Retrieved Context\n\n"
for i, chunk in enumerate(chunks):
path = chunk.get("metadata", {}).get("path", "unknown")
context_block += f"### Chunk {i+1} (Source: {path})\n{chunk.get('document', '')}\n\n"
user_msg = context_block + user_msg
except Exception as e:
sys.stderr.write(f"RAG search error: {e}\n")
rag_result = controller._rag_search_result(user_msg)
if rag_result.ok and rag_result.data:
context_block = "## Retrieved Context\n\n"
for i, chunk in enumerate(rag_result.data):
path = chunk.get("metadata", {}).get("path", "unknown")
context_block += f"### Chunk {i+1} (Source: {path})\n{chunk.get('document', '')}\n\n"
user_msg = context_block + user_msg
elif not rag_result.ok:
controller._last_request_errors.append(("rag_search", rag_result.errors[0]))
sys.stderr.write(f"RAG search error: {rag_result.errors[0].ui_message()}\n")
sys.stderr.flush()
# 3. Symbol Resolution
try:
from src.markdown_helper import parse_symbols, get_symbol_definition
symbols = parse_symbols(user_msg)
file_paths = [f.path if hasattr(f, "path") else f.get("path") if isinstance(f, dict) else str(f) for f in controller.last_file_items]
for symbol in symbols:
res = get_symbol_definition(symbol, file_paths)
if res:
file_path, definition, line = res
user_msg += f'\n\n[Definition: {symbol} from {file_path} (line {line})]\n```python\n{definition}\n```'
except Exception as e:
sys.stderr.write(f"Symbol resolution error: {e}\n")
# 3. Symbol Resolution (Phase 7: delegates to _symbol_resolution_result; error carried in _last_request_errors)
sym_result = controller._symbol_resolution_result(
user_msg,
[f.path if hasattr(f, "path") else f.get("path") if isinstance(f, dict) else str(f) for f in controller.last_file_items],
)
if sym_result.ok and sym_result.data != user_msg:
user_msg = sym_result.data
elif not sym_result.ok:
controller._last_request_errors.append(("symbol_resolution", sym_result.errors[0]))
sys.stderr.write(f"Symbol resolution error: {sym_result.errors[0].ui_message()}\n")
sys.stderr.flush()
base_dir = controller.active_project_root