Skip to main content
Glama
test_error_messages.py6.65 kB
""" Error Message Validation Tests Verify that error messages: - Contain actionable information - Have consistent error codes - Include relevant context - Are user-friendly """ from __future__ import annotations import pytest from spice_mcp.core.errors import error_response def test_error_response_includes_context(): """Test that error responses include helpful context.""" error = ValueError("Invalid query parameter") context = {"tool": "dune_query", "query": "SELECT 1", "query_type": "raw_sql"} result = error_response(error, context=context) assert "ok" in result assert result["ok"] is False assert "error" in result assert "code" in result["error"] assert "message" in result["error"] assert "context" in result["error"] # Context should include provided information assert result["error"]["context"]["tool"] == "dune_query" assert result["error"]["context"]["query"] == "SELECT 1" def test_error_codes_are_consistent(): """Test that error codes follow consistent patterns.""" from spice_mcp.mcp.tools.execute_query import ExecuteQueryTool from spice_mcp.config import Config, DuneConfig from spice_mcp.logging.query_history import DisabledQueryHistory class FailingQueryService: def execute(self, **kwargs): raise TimeoutError("Query timed out after 30 seconds") tool = ExecuteQueryTool( Config(dune=DuneConfig(api_key="test")), FailingQueryService(), DisabledQueryHistory(), ) result = tool.execute(query="SELECT 1", format="preview") assert result["ok"] is False assert "error" in result assert "code" in result["error"] # Timeout errors should have specific code assert result["error"]["code"] == "QUERY_TIMEOUT" def test_error_messages_are_actionable(): """Test that error messages provide actionable guidance.""" from spice_mcp.mcp.tools.execute_query import ExecuteQueryTool from spice_mcp.config import Config, DuneConfig from spice_mcp.logging.query_history import DisabledQueryHistory class FailingQueryService: def execute(self, **kwargs): raise RuntimeError("429 rate limit exceeded") tool = ExecuteQueryTool( Config(dune=DuneConfig(api_key="test")), FailingQueryService(), DisabledQueryHistory(), ) result = tool.execute(query="SELECT 1", format="preview") assert result["ok"] is False assert "error" in result assert "message" in result["error"] # Error message should be present and not empty message = result["error"]["message"] assert len(message) > 0 assert isinstance(message, str) def test_error_context_includes_debug_info(): """Test that error context includes debugging information when available.""" from spice_mcp.mcp.tools.execute_query import ExecuteQueryTool from spice_mcp.config import Config, DuneConfig from spice_mcp.logging.query_history import DisabledQueryHistory class FailingQueryService: def execute(self, **kwargs): raise Exception("could not determine execution") tool = ExecuteQueryTool( Config(dune=DuneConfig(api_key="test")), FailingQueryService(), DisabledQueryHistory(), ) result = tool.execute(query="SELECT 1", format="preview") assert result["ok"] is False assert "error" in result assert "context" in result["error"] # For raw SQL failures, should include debug info context = result["error"]["context"] if "debug_info" in context: assert len(context["debug_info"]) > 0 def test_timeout_errors_have_specific_code(): """Test that timeout errors use the QUERY_TIMEOUT code.""" from spice_mcp.mcp.tools.execute_query import ExecuteQueryTool from spice_mcp.config import Config, DuneConfig from spice_mcp.logging.query_history import DisabledQueryHistory class TimeoutQueryService: def execute(self, **kwargs): raise TimeoutError("Query execution timed out") tool = ExecuteQueryTool( Config(dune=DuneConfig(api_key="test")), TimeoutQueryService(), DisabledQueryHistory(), ) result = tool.execute(query="SELECT 1", format="preview") assert result["ok"] is False assert result["error"]["code"] == "QUERY_TIMEOUT" def test_rate_limit_errors_have_specific_code(): """Test that rate limit errors use the RATE_LIMIT code.""" from spice_mcp.mcp.tools.execute_query import ExecuteQueryTool from spice_mcp.config import Config, DuneConfig from spice_mcp.logging.query_history import DisabledQueryHistory class RateLimitQueryService: def execute(self, **kwargs): raise RuntimeError("429 rate limit exceeded") tool = ExecuteQueryTool( Config(dune=DuneConfig(api_key="test")), RateLimitQueryService(), DisabledQueryHistory(), ) result = tool.execute(query="SELECT 1", format="preview") assert result["ok"] is False assert result["error"]["code"] == "RATE_LIMIT" def test_error_messages_include_query_info(): """Test that error messages include relevant query information.""" from spice_mcp.mcp.tools.execute_query import ExecuteQueryTool from spice_mcp.config import Config, DuneConfig from spice_mcp.logging.query_history import DisabledQueryHistory class FailingQueryService: def execute(self, **kwargs): raise ValueError("Invalid SQL syntax") tool = ExecuteQueryTool( Config(dune=DuneConfig(api_key="test")), FailingQueryService(), DisabledQueryHistory(), ) test_query = "SELECTTTT INVALID" result = tool.execute(query=test_query, format="preview") assert result["ok"] is False assert "error" in result assert "context" in result["error"] # Context should include the query (possibly truncated) context = result["error"]["context"] assert "query" in context or "query_preview" in context def test_error_responses_are_serializable(): """Test that error responses can be serialized to JSON.""" import json error = ValueError("Test error") context = {"tool": "test_tool", "param": "value"} result = error_response(error, context=context) # Should be JSON serializable json_str = json.dumps(result) assert len(json_str) > 0 # Should be able to deserialize parsed = json.loads(json_str) assert parsed["ok"] is False assert "error" in parsed

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Evan-Kim2028/spice-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server