bhupesh-sf's picture
first commit
f8ba6bf verified
"""
DungeonMaster AI - MCP Integration Exceptions
Custom exception hierarchy for clear error handling in MCP operations.
"""
from __future__ import annotations
class MCPIntegrationError(Exception):
"""Base exception for all MCP integration errors."""
def __init__(self, message: str = "An MCP integration error occurred") -> None:
self.message = message
super().__init__(self.message)
class MCPConnectionError(MCPIntegrationError):
"""Raised when connection to MCP server fails."""
def __init__(
self,
message: str = "Failed to connect to MCP server",
url: str | None = None,
) -> None:
self.url = url
if url:
message = f"{message}: {url}"
super().__init__(message)
class MCPTimeoutError(MCPIntegrationError):
"""Raised when an MCP operation times out."""
def __init__(
self,
message: str = "MCP operation timed out",
timeout_seconds: float | None = None,
operation: str | None = None,
) -> None:
self.timeout_seconds = timeout_seconds
self.operation = operation
if timeout_seconds and operation:
message = f"{message}: {operation} after {timeout_seconds}s"
elif timeout_seconds:
message = f"{message} after {timeout_seconds}s"
super().__init__(message)
class MCPToolNotFoundError(MCPIntegrationError):
"""Raised when a requested tool does not exist."""
def __init__(self, tool_name: str) -> None:
self.tool_name = tool_name
super().__init__(f"Tool not found: {tool_name}")
class MCPToolExecutionError(MCPIntegrationError):
"""Raised when tool execution fails."""
def __init__(
self,
tool_name: str,
original_error: Exception | None = None,
message: str | None = None,
) -> None:
self.tool_name = tool_name
self.original_error = original_error
if message:
error_msg = message
elif original_error:
error_msg = f"Tool '{tool_name}' execution failed: {original_error}"
else:
error_msg = f"Tool '{tool_name}' execution failed"
super().__init__(error_msg)
class MCPUnavailableError(MCPIntegrationError):
"""Raised when the MCP server is unavailable."""
def __init__(
self,
message: str = "MCP server is currently unavailable",
reason: str | None = None,
) -> None:
self.reason = reason
if reason:
message = f"{message}: {reason}"
super().__init__(message)
class MCPCircuitBreakerOpenError(MCPIntegrationError):
"""Raised when the circuit breaker is open and rejecting requests."""
def __init__(
self,
message: str = "Circuit breaker is open - too many recent failures",
retry_after_seconds: float | None = None,
) -> None:
self.retry_after_seconds = retry_after_seconds
if retry_after_seconds:
message = f"{message}. Retry after {retry_after_seconds:.1f}s"
super().__init__(message)
class MCPInvalidResponseError(MCPIntegrationError):
"""Raised when MCP server returns an invalid or unexpected response."""
def __init__(
self,
message: str = "Invalid response from MCP server",
tool_name: str | None = None,
response: object | None = None,
) -> None:
self.tool_name = tool_name
self.response = response
if tool_name:
message = f"{message} for tool '{tool_name}'"
super().__init__(message)