Skip to content

Commit d7bacda

Browse files
committed
fix: add raise ... from e in all except handlers
Preserves exception chaining so the original traceback is always visible when exceptions are re-raised inside except blocks. Fixes 11 sites across 6 files — follow-up to #2542.
1 parent 19fe9fa commit d7bacda

6 files changed

Lines changed: 11 additions & 11 deletions

File tree

src/mcp/client/auth/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ async def handle_registration_response(response: Response) -> OAuthClientInforma
241241
client_info = OAuthClientInformationFull.model_validate_json(content)
242242
return client_info
243243
except ValidationError as e: # pragma: no cover
244-
raise OAuthRegistrationError(f"Invalid registration response: {e}")
244+
raise OAuthRegistrationError(f"Invalid registration response: {e}") from e
245245

246246

247247
def is_valid_client_metadata_url(url: str | None) -> bool:
@@ -334,4 +334,4 @@ async def handle_token_response_scopes(
334334
token_response = OAuthToken.model_validate_json(content)
335335
return token_response
336336
except ValidationError as e: # pragma: no cover
337-
raise OAuthTokenError(f"Invalid token response: {e}")
337+
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
@@ -316,9 +316,9 @@ async def _validate_tool_result(self, name: str, result: types.CallToolResult) -
316316
try:
317317
validate(result.structured_content, output_schema)
318318
except ValidationError as e:
319-
raise RuntimeError(f"Invalid structured content returned by tool {name}: {e}")
319+
raise RuntimeError(f"Invalid structured content returned by tool {name}: {e}") from e
320320
except SchemaError as e: # pragma: no cover
321-
raise RuntimeError(f"Invalid schema for tool {name}: {e}") # pragma: no cover
321+
raise RuntimeError(f"Invalid schema for tool {name}: {e}") from e # pragma: no cover
322322

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

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,4 +186,4 @@ async def render(
186186

187187
return messages
188188
except Exception as e:
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)