Skip to main content
Glama
ERROR_HANDLING.md6.48 kB
# MCP Tool Error Handling This document describes the error handling architecture for igloo-mcp MCP tools. ## Overview All MCP tools use a consistent exception-based error handling pattern: 1. Tools raise MCP-specific exceptions (`MCPValidationError`, `MCPExecutionError`, `MCPSelectorError`) 2. The `@tool_error_handler` decorator ensures all exceptions are properly formatted 3. FastMCP serializes exceptions to JSON-RPC error responses 4. All errors include `request_id` for correlation and timing information ## Exception Types ### MCPValidationError Raised when tool parameters fail validation (invalid types, missing required fields, out-of-range values). **Key Features:** - Includes `validation_errors` list with specific field-level errors - Provides actionable `hints` with parameter-specific guidance - Includes `context` with `request_id` and operation details ### MCPExecutionError Raised when tool execution fails (database errors, file I/O errors, runtime failures). **Key Features:** - Includes `operation` name for identification - Preserves `original_error` for debugging - Provides `hints` for troubleshooting - Includes `context` with `request_id` and operation details ### MCPSelectorError Raised when a selector (ID, name, etc.) cannot be resolved. **Key Features:** - Includes `selector` that failed - Specifies `error` type ("not_found", "ambiguous", "invalid_format") - Provides `candidates` list for ambiguous errors - Includes `context` with `request_id` ## Error Handler Decorator The `@tool_error_handler` decorator in `src/igloo_mcp/mcp/tools/base.py`: 1. **Preserves MCP exceptions**: Re-raises MCP exceptions as-is (they're already properly formatted) 2. **Converts ValidationError**: Converts Pydantic `ValidationError` to `MCPValidationError` with detailed field paths 3. **Converts other exceptions**: Wraps unexpected exceptions in `MCPExecutionError` with context 4. **Adds request_id**: Automatically includes `request_id` from kwargs in error context 5. **Logs errors**: Logs all errors with context for debugging ## FastMCP Serialization FastMCP automatically serializes exceptions raised from tool handlers to JSON-RPC error responses. The serialization process: 1. **Exception Detection**: FastMCP catches exceptions raised from tool handlers 2. **to_dict() Call**: If the exception has a `to_dict()` method, FastMCP calls it 3. **JSON-RPC Format**: The result is formatted as a JSON-RPC error response 4. **Error Code Mapping**: FastMCP maps exception types to appropriate JSON-RPC error codes **Note**: All MCP exception classes (`MCPToolError`, `MCPValidationError`, `MCPExecutionError`, `MCPSelectorError`) implement `to_dict()` methods that return structured error dictionaries. ## Request ID Generation All tools automatically generate a `request_id` if not provided: ```python from igloo_mcp.mcp.tools.base import ensure_request_id request_id = ensure_request_id(request_id) # Generates UUID if None ``` The `request_id` is: - Included in all error responses via `context` - Logged with all operations - Included in successful responses for correlation ## Timing Information Tools capture timing information for performance monitoring: ```python start_time = time.time() # ... operation ... duration_ms = (time.time() - start_time) * 1000 ``` Timing is included in: - Successful responses: `timing` field with operation-specific durations - Error responses: Available in logs via `request_id` correlation ## Error Response Format ### Success Response ```json { "status": "success", "request_id": "uuid-here", "timing": { "operation_duration_ms": 123.45, "total_duration_ms": 150.67 }, "data": {...} } ``` ### Error Response (via FastMCP) ```json { "code": -32603, "message": "Tool execution failed: ...", "data": { "message": "Human-readable error message", "error_type": "MCPValidationError", "error_code": "VALIDATION_ERROR", "validation_errors": ["field: error message"], "hints": ["actionable", "suggestions"], "context": { "request_id": "uuid-here", "operation": "tool_name" } } } ``` ## Best Practices 1. **Always use @tool_error_handler**: Ensures consistent error formatting 2. **Raise specific exceptions**: Use `MCPValidationError`, `MCPExecutionError`, or `MCPSelectorError` 3. **Include request_id**: Use `ensure_request_id()` helper 4. **Provide actionable hints**: Include specific parameter names and examples 5. **Capture timing**: Include timing information in responses 6. **Log with context**: Include `request_id` in all log statements ## Error Aggregation The `ErrorAggregator` class in `src/igloo_mcp/error_handling.py` provides functionality for aggregating errors during batch operations. Currently, it's available but not actively used in MCP tools. **Current Status:** Available for future batch operation implementations **Usage Example:** ```python from igloo_mcp.error_handling import ErrorAggregator aggregator = ErrorAggregator() # Process multiple items for item in items: try: process_item(item) except Exception as e: aggregator.add_error(item.id, e) if aggregator.has_errors(): summary = aggregator.get_summary() # Handle aggregated errors ``` **Potential Use Cases:** - Batch report operations (create/evolve multiple reports) - Bulk catalog operations - Parallel query execution with error collection **Note:** For single-operation tools, exceptions are raised immediately. ErrorAggregator would be useful for future batch operation tools. ## Testing Error Handling Error handling is tested in: - `tests/test_*_tool.py` - Individual tool error scenarios - `tests/test_mcp_error_handling.py` - Request ID, error context, exception serialization - `tests/test_error_handling.py` - Error handler decorator and ErrorAggregator behavior - `tests/test_evolve_report_mcp.py` - Evolve report error scenarios - `tests/test_render_report_tool.py` - Render report error scenarios - `tests/test_create_report_tool.py` - Create report error scenarios ## Migration Notes If migrating from dict-based error responses to exception-based: 1. **Remove status dicts**: Don't return `{"status": "error", ...}` - raise exceptions instead 2. **Use MCP exceptions**: Import and raise `MCPValidationError`, `MCPExecutionError`, `MCPSelectorError` 3. **Add request_id**: Use `ensure_request_id()` helper 4. **Update tests**: Test exception raising instead of dict responses

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/igloo-mcp'

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