fix: clarify missing MCP stdio command errors (#5992)

* fix: clarify missing MCP stdio command errors

* refactor: tighten MCP error presentation helpers

* fix: improve MCP test connection feedback

* fix: structure MCP test connection errors

* refactor: share MCP test error codes
This commit is contained in:
エイカク
2026-03-10 23:05:50 +09:00
committed by GitHub
parent ec21cb13d3
commit 0c771e4a77
13 changed files with 349 additions and 27 deletions
+86 -1
View File
@@ -3,6 +3,7 @@ import io
import os
import sys
import zipfile
from contextlib import asynccontextmanager
from datetime import datetime
from types import SimpleNamespace
@@ -16,6 +17,11 @@ from astrbot.core.core_lifecycle import AstrBotCoreLifecycle
from astrbot.core.db.sqlite import SQLiteDatabase
from astrbot.core.star.star import star_registry
from astrbot.core.star.star_handler import star_handlers_registry
from astrbot.core.agent import mcp_client as mcp_client_module
from astrbot.dashboard.shared import (
MCP_STDIO_COMMAND_NOT_FOUND,
MCP_TEST_CONNECTION_FAILED,
)
from astrbot.dashboard.routes.plugin import PluginRoute
from astrbot.dashboard.server import AstrBotDashboard
from tests.fixtures.helpers import (
@@ -270,10 +276,89 @@ async def test_commands_api(app: Quart, authenticated_header: dict):
assert response.status_code == 200
data = await response.get_json()
assert data["status"] == "ok"
# conflicts is a list
assert isinstance(data["data"], list)
@pytest.mark.asyncio
async def test_mcp_test_connection_returns_clear_missing_stdio_command_message(
app: Quart,
authenticated_header: dict,
monkeypatch,
):
test_client = app.test_client()
@asynccontextmanager
async def fake_stdio_client(*args, **kwargs):
raise FileNotFoundError(2, "系统找不到指定的文件。")
yield
monkeypatch.setattr(mcp_client_module.mcp, "stdio_client", fake_stdio_client)
response = await test_client.post(
"/api/tools/mcp/test",
json={
"mcp_server_config": {
"command": "uvx",
"args": ["mcp-server-fetch"],
}
},
headers=authenticated_header,
)
assert response.status_code == 200
data = await response.get_json()
assert data["status"] == "error"
assert data["message"] == "Unable to test the MCP connection. Review the details below."
assert data["data"] == {
"error": {
"code": MCP_STDIO_COMMAND_NOT_FOUND,
"command": "uvx",
"raw_error": "[Errno 2] 系统找不到指定的文件。",
}
}
@pytest.mark.asyncio
async def test_mcp_test_connection_uses_fallback_for_blank_error_message(
app: Quart,
authenticated_header: dict,
core_lifecycle_td: AstrBotCoreLifecycle,
monkeypatch,
):
test_client = app.test_client()
async def raise_blank_error(*args, **kwargs):
raise Exception(" ")
monkeypatch.setattr(
core_lifecycle_td.provider_manager.llm_tools,
"test_mcp_server_connection",
raise_blank_error,
)
response = await test_client.post(
"/api/tools/mcp/test",
json={
"mcp_server_config": {
"command": "uvx",
"args": ["mcp-server-fetch"],
}
},
headers=authenticated_header,
)
assert response.status_code == 200
data = await response.get_json()
assert data["status"] == "error"
assert data["message"] == "Unable to test the MCP connection."
assert data["data"] == {
"error": {
"code": MCP_TEST_CONNECTION_FAILED,
"detail": "Unable to test the MCP connection.",
}
}
@pytest.mark.asyncio
async def test_check_update(
app: Quart,