Coverage for src / lexigram / contracts / mcp / exceptions.py: 100%
54 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-19 05:41 +0800
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-19 05:41 +0800
1"""MCP exception hierarchy for the Lexigram framework.
3MCP-specific errors that can occur during MCP server operation.
4These extend the base LexigramError for consistent error handling.
5"""
7from __future__ import annotations
9from typing import Any
11from lexigram.contracts.exceptions.base import LexigramError
14class MCPError(LexigramError):
15 """Base exception for all MCP errors."""
17 _code = "LEX_ERR_MCP_001"
19 def __init__(self, message: str = "MCP error", **kwargs: Any) -> None:
20 super().__init__(
21 message=message,
22 **kwargs,
23 )
26class MCPTransportError(MCPError):
27 """Transport-level error (connection, I/O).
29 Raised when the MCP transport layer encounters errors
30 such as connection failures, timeouts, or I/O errors.
31 """
33 _code = "LEX_ERR_MCP_002"
35 def __init__(
36 self,
37 message: str = "MCP transport error",
38 *,
39 transport_type: str | None = None,
40 **kwargs: Any,
41 ) -> None:
42 details = kwargs.pop("details", {})
43 if transport_type:
44 details["transport"] = transport_type
45 super().__init__(
46 message=message,
47 details=details,
48 **kwargs,
49 )
52class MCPToolCallError(MCPError):
53 """Tool call failed during MCP execution.
55 Raised when a tool invocation fails, either due to
56 the tool not existing or raising an exception.
57 """
59 _code = "LEX_ERR_MCP_003"
61 def __init__(
62 self,
63 message: str = "MCP tool call failed",
64 *,
65 tool_name: str | None = None,
66 **kwargs: Any,
67 ) -> None:
68 details = kwargs.pop("details", {})
69 if tool_name:
70 details["tool"] = tool_name
71 super().__init__(
72 message=message,
73 details=details,
74 **kwargs,
75 )
78class MCPResourceError(MCPError):
79 """Resource read or list failed.
81 Raised when a resource operation fails, such as
82 when a resource is not found or cannot be read.
83 """
85 _code = "LEX_ERR_MCP_004"
87 def __init__(
88 self,
89 message: str = "MCP resource error",
90 *,
91 uri: str | None = None,
92 **kwargs: Any,
93 ) -> None:
94 details = kwargs.pop("details", {})
95 if uri:
96 details["uri"] = uri
97 super().__init__(
98 message=message,
99 details=details,
100 **kwargs,
101 )
104class MCPProtocolError(MCPError):
105 """Protocol violation (malformed message, invalid state).
107 Raised when an MCP message violates the protocol specification,
108 such as missing required fields or invalid JSON-RPC structure.
109 """
111 _code = "LEX_ERR_MCP_005"
113 def __init__(
114 self,
115 message: str = "MCP protocol error",
116 *,
117 details: dict[str, Any] | None = None,
118 **kwargs: Any,
119 ) -> None:
120 super().__init__(
121 message=message,
122 details=details or {},
123 **kwargs,
124 )
127class MCPMethodNotFoundError(MCPError):
128 """Unknown MCP method requested by client.
130 Raised when the client requests an MCP method that
131 the server does not support.
132 """
134 _code = "LEX_ERR_MCP_006"
136 def __init__(
137 self,
138 message: str = "MCP method not found",
139 *,
140 method: str | None = None,
141 **kwargs: Any,
142 ) -> None:
143 details = kwargs.pop("details", {})
144 if method:
145 details["method"] = method
146 super().__init__(
147 message=message,
148 details=details,
149 **kwargs,
150 )
153class MCPPromptError(MCPError):
154 """Prompt retrieval or list failed.
156 Raised when a prompt operation fails, such as
157 when a prompt is not found or arguments are invalid.
158 """
160 _code = "LEX_ERR_MCP_007"
162 def __init__(
163 self,
164 message: str = "MCP prompt error",
165 *,
166 prompt_name: str | None = None,
167 **kwargs: Any,
168 ) -> None:
169 details = kwargs.pop("details", {})
170 if prompt_name:
171 details["prompt"] = prompt_name
172 super().__init__(
173 message=message,
174 details=details,
175 **kwargs,
176 )
179class MCPInitializationError(MCPError):
180 """MCP server initialization failed.
182 Raised when the MCP server cannot be initialized,
183 usually due to missing required handlers or
184 configuration errors.
185 """
187 _code = "LEX_ERR_MCP_008"
189 def __init__(
190 self,
191 message: str = "MCP initialization failed",
192 *,
193 reason: str | None = None,
194 **kwargs: Any,
195 ) -> None:
196 details = kwargs.pop("details", {})
197 if reason:
198 details["reason"] = reason
199 super().__init__(
200 message=message,
201 details=details,
202 **kwargs,
203 )
206__all__ = [
207 "MCPError",
208 "MCPInitializationError",
209 "MCPMethodNotFoundError",
210 "MCPPromptError",
211 "MCPProtocolError",
212 "MCPResourceError",
213 "MCPToolCallError",
214 "MCPTransportError",
215]