Skip to content

Commit 46c8017

Browse files
fix: chain exceptions with from in 12 remaining raise sites
Fixes #2564
1 parent 161834d commit 46c8017

7 files changed

Lines changed: 15 additions & 15 deletions

File tree

src/mcp/client/auth/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ async def handle_registration_response(response: Response) -> OAuthClientInforma
243243
# self.context.client_info = client_info
244244
# await self.context.storage.set_client_info(client_info)
245245
except ValidationError as e: # pragma: no cover
246-
raise OAuthRegistrationError(f"Invalid registration response: {e}")
246+
raise OAuthRegistrationError(f"Invalid registration response: {e}") from e
247247

248248

249249
def is_valid_client_metadata_url(url: str | None) -> bool:
@@ -336,4 +336,4 @@ async def handle_token_response_scopes(
336336
token_response = OAuthToken.model_validate_json(content)
337337
return token_response
338338
except ValidationError as e: # pragma: no cover
339-
raise OAuthTokenError(f"Invalid token response: {e}")
339+
raise OAuthTokenError(f"Invalid token response: {e}") from e

src/mcp/client/session.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,9 +343,9 @@ async def _validate_tool_result(self, name: str, result: types.CallToolResult) -
343343
try:
344344
validate(result.structured_content, output_schema)
345345
except ValidationError as e:
346-
raise RuntimeError(f"Invalid structured content returned by tool {name}: {e}")
346+
raise RuntimeError(f"Invalid structured content returned by tool {name}: {e}") from e
347347
except SchemaError as e: # pragma: no cover
348-
raise RuntimeError(f"Invalid schema for tool {name}: {e}") # pragma: no cover
348+
raise RuntimeError(f"Invalid schema for tool {name}: {e}") from e # pragma: no cover
349349

350350
async def list_prompts(self, *, params: types.PaginatedRequestParams | None = None) -> types.ListPromptsResult:
351351
"""Send a prompts/list request.

src/mcp/server/auth/middleware/client_auth.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ async def authenticate_request(self, request: Request) -> OAuthClientInformation
8080

8181
if basic_client_id != client_id:
8282
raise AuthenticationError("Client ID mismatch in Basic auth")
83-
except (ValueError, UnicodeDecodeError, binascii.Error):
84-
raise AuthenticationError("Invalid Basic authentication header")
83+
except (ValueError, UnicodeDecodeError, binascii.Error) as exc:
84+
raise AuthenticationError("Invalid Basic authentication header") from exc
8585

8686
elif client.token_endpoint_auth_method == "client_secret_post":
8787
raw_form_data = form_data.get("client_secret")

src/mcp/server/mcpserver/prompts/base.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,9 @@ async def render(
181181
else: # pragma: no cover
182182
content = pydantic_core.to_json(msg, fallback=str, indent=2).decode()
183183
messages.append(Message(role="user", content=content))
184-
except Exception: # pragma: no cover
185-
raise ValueError(f"Could not convert prompt result to message: {msg}")
184+
except Exception as e: # pragma: no cover
185+
raise ValueError(f"Could not convert prompt result to message: {msg}") from e
186186

187187
return messages
188188
except Exception as e: # pragma: no cover
189-
raise ValueError(f"Error rendering prompt {self.name}: {e}")
189+
raise ValueError(f"Error rendering prompt {self.name}: {e}") from e

src/mcp/server/mcpserver/resources/resource_manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ async def get_resource(self, uri: AnyUrl | str, context: Context[LifespanContext
9393
try:
9494
return await template.create_resource(uri_str, params, context=context)
9595
except Exception as e: # pragma: no cover
96-
raise ValueError(f"Error creating resource from template: {e}")
96+
raise ValueError(f"Error creating resource from template: {e}") from e
9797

9898
raise ValueError(f"Unknown resource: {uri}")
9999

src/mcp/server/mcpserver/resources/templates.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,4 @@ async def create_resource(
130130
fn=lambda: result, # Capture result in closure
131131
)
132132
except Exception as e:
133-
raise ValueError(f"Error creating resource from template: {e}")
133+
raise ValueError(f"Error creating resource from template: {e}") from e

src/mcp/server/mcpserver/resources/types.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ async def read(self) -> str | bytes:
7272
else:
7373
return pydantic_core.to_json(result, fallback=str, indent=2).decode()
7474
except Exception as e:
75-
raise ValueError(f"Error reading resource {self.uri}: {e}")
75+
raise ValueError(f"Error reading resource {self.uri}: {e}") from e
7676

7777
@classmethod
7878
def from_function(
@@ -148,7 +148,7 @@ async def read(self) -> str | bytes:
148148
return await anyio.to_thread.run_sync(self.path.read_bytes)
149149
return await anyio.to_thread.run_sync(self.path.read_text)
150150
except Exception as e:
151-
raise ValueError(f"Error reading file {self.path}: {e}")
151+
raise ValueError(f"Error reading file {self.path}: {e}") from e
152152

153153

154154
class HttpResource(Resource):
@@ -193,7 +193,7 @@ def list_files(self) -> list[Path]: # pragma: no cover
193193
return list(self.path.glob(self.pattern)) if not self.recursive else list(self.path.rglob(self.pattern))
194194
return list(self.path.glob("*")) if not self.recursive else list(self.path.rglob("*"))
195195
except Exception as e:
196-
raise ValueError(f"Error listing directory {self.path}: {e}")
196+
raise ValueError(f"Error listing directory {self.path}: {e}") from e
197197

198198
async def read(self) -> str: # Always returns JSON string # pragma: no cover
199199
"""Read the directory listing."""
@@ -202,4 +202,4 @@ async def read(self) -> str: # Always returns JSON string # pragma: no cover
202202
file_list = [str(f.relative_to(self.path)) for f in files if f.is_file()]
203203
return json.dumps({"files": file_list}, indent=2)
204204
except Exception as e:
205-
raise ValueError(f"Error reading directory {self.path}: {e}")
205+
raise ValueError(f"Error reading directory {self.path}: {e}") from e

0 commit comments

Comments
 (0)