Private
Public Access
0
0

refactor(mcp_client): migrate L1661+L1666 stop to Result-drain pattern (Phase 8 sites 2+3)

The legacy StdioMCPServer.stop() had 2 'try/except Exception: pass' blocks
(silent-swallow). Migrated to capture errors as ErrorInfo list and surface
them via the [MCP:<name>:stop-warning] drain (print to stdout, consistent
with _read_stderr's existing stderr-drain pattern).

No logging-only or pass-only: errors are accumulated into ErrorInfo with
the original exception preserved. The drain is a visible stdout print,
which is a true drain (operator sees it during shutdown).

Audit: mcp_client INTERNAL_SILENT_SWALLOW 2 -> 0. Total mcp_client migration-target sites: 0.
This commit is contained in:
2026-06-20 10:43:14 -04:00
parent 87f8c0575d
commit e51cbd2c0f
+13 -6
View File
@@ -1652,19 +1652,26 @@ class StdioMCPServer:
async def stop(self):
"""
[C: tests/test_performance_monitor.py:test_perf_monitor_basic_timing, tests/test_performance_monitor.py:test_perf_monitor_component_timing, tests/test_performance_monitor.py:test_perf_monitor_extended_metrics, tests/test_performance_monitor.py:test_perf_monitor_scope_context_manager, tests/test_websocket_server.py:test_websocket_subscription_and_broadcast]
Best-effort cleanup. Errors during cleanup are accumulated as ErrorInfo and
surfaced via the [MCP:<name>:stop-warning] drain (consistent with _read_stderr
which also uses print() as a stderr/stdout drain for visibility).
"""
if self.proc:
try:
if self.proc.stdin:
errors: list[ErrorInfo] = []
if self.proc.stdin:
try:
self.proc.stdin.close()
await self.proc.stdin.wait_closed()
except Exception:
pass
except Exception as e:
errors.append(ErrorInfo(kind=ErrorKind.INTERNAL, message=f"stdin close: {e}", source="mcp.StdioMCPServer.stop", original=e))
try:
self.proc.terminate()
await self.proc.wait()
except Exception:
pass
except Exception as e:
errors.append(ErrorInfo(kind=ErrorKind.INTERNAL, message=f"terminate: {e}", source="mcp.StdioMCPServer.stop", original=e))
for err in errors:
print(f"[MCP:{self.name}:stop-warning] {err.ui_message()}")
self.proc = None
self.status = 'idle'