Skip to content

Commit fcf6d7f

Browse files
committed
fix(mcp): wrap _fetch calls in try/except per graceful HTTP error handling
Ogni tool MCP ora cattura requests.HTTPError e restituisce una stringa di errore contestuale invece di crashare. Aggiunti 3 test per i casi 403, 404, 500 su session_bootstrap, workspace_triage e topic_index.
1 parent 8df9cfb commit fcf6d7f

2 files changed

Lines changed: 57 additions & 3 deletions

File tree

src/agent_context_builder/mcp_server.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,19 +125,28 @@ def _fetch(path: str) -> str:
125125
@mcp.tool()
126126
def session_bootstrap() -> str:
127127
"""Orientamento rapido: repo attivi, PR aperte, discussion, stato locale, topic."""
128-
return _fetch("session_bootstrap.md")
128+
try:
129+
return _fetch("session_bootstrap.md")
130+
except requests.HTTPError as e:
131+
return f"session_bootstrap: {e}"
129132

130133

131134
@mcp.tool()
132135
def workspace_triage() -> str:
133136
"""Triage machine-readable: PR, issue, discussion, stato git per repo, warning."""
134-
return _fetch("workspace_triage.json")
137+
try:
138+
return _fetch("workspace_triage.json")
139+
except requests.HTTPError as e:
140+
return f"workspace_triage: {e}"
135141

136142

137143
@mcp.tool()
138144
def topic_index() -> str:
139145
"""Topic index v2 — repos, datasets_by_source, operational_topics."""
140-
return _fetch("topic_index.json")
146+
try:
147+
return _fetch("topic_index.json")
148+
except requests.HTTPError as e:
149+
return f"topic_index: {e}"
141150

142151

143152
@mcp.tool()

tests/test_mcp_server.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Tests for MCP server resources and tools."""
22

3+
import requests
34
from unittest.mock import MagicMock, patch
45

56

@@ -143,3 +144,47 @@ def test_refresh_context_api_error(monkeypatch):
143144
result = refresh_context()
144145

145146
assert "403" in result
147+
148+
149+
def _mock_http_error(status: int):
150+
"""Return a mock raising HTTPError."""
151+
response = _mock_response("error", status=status)
152+
exc = requests.HTTPError(f"{status} Client Error", response=response)
153+
response.raise_for_status.side_effect = exc
154+
return response
155+
156+
157+
def test_session_bootstrap_http_error(monkeypatch):
158+
"""session_bootstrap returns error string on HTTP failure instead of raising."""
159+
from agent_context_builder.mcp_server import session_bootstrap
160+
161+
with patch("agent_context_builder.mcp_server.requests.get") as mock_get:
162+
mock_get.return_value = _mock_http_error(403)
163+
result = session_bootstrap()
164+
165+
assert "session_bootstrap" in result
166+
assert "403" in result
167+
168+
169+
def test_workspace_triage_http_error(monkeypatch):
170+
"""workspace_triage returns error string on HTTP failure instead of raising."""
171+
from agent_context_builder.mcp_server import workspace_triage
172+
173+
with patch("agent_context_builder.mcp_server.requests.get") as mock_get:
174+
mock_get.return_value = _mock_http_error(404)
175+
result = workspace_triage()
176+
177+
assert "workspace_triage" in result
178+
assert "404" in result
179+
180+
181+
def test_topic_index_http_error(monkeypatch):
182+
"""topic_index returns error string on HTTP failure instead of raising."""
183+
from agent_context_builder.mcp_server import topic_index
184+
185+
with patch("agent_context_builder.mcp_server.requests.get") as mock_get:
186+
mock_get.return_value = _mock_http_error(500)
187+
result = topic_index()
188+
189+
assert "topic_index" in result
190+
assert "500" in result

0 commit comments

Comments
 (0)