|
1 | 1 | """Tests for MCP exception classes.""" |
2 | 2 |
|
| 3 | +import pickle |
| 4 | + |
3 | 5 | import pytest |
4 | 6 |
|
5 | 7 | from mcp.shared.exceptions import McpError, UrlElicitationRequiredError |
6 | 8 | from mcp.types import URL_ELICITATION_REQUIRED, ElicitRequestURLParams, ErrorData |
7 | 9 |
|
8 | 10 |
|
| 11 | +def test_mcp_error_pickle_roundtrip() -> None: |
| 12 | + """Test that McpError preserves its wire payload through pickle.""" |
| 13 | + original = McpError(ErrorData(code=-32600, message="Authentication Required", data={"retry": True})) |
| 14 | + |
| 15 | + reconstructed = pickle.loads(pickle.dumps(original)) |
| 16 | + |
| 17 | + assert isinstance(reconstructed, McpError) |
| 18 | + assert reconstructed.error == original.error |
| 19 | + assert str(reconstructed) == str(original) |
| 20 | + |
| 21 | + |
9 | 22 | class TestUrlElicitationRequiredError: |
10 | 23 | """Tests for UrlElicitationRequiredError exception class.""" |
11 | 24 |
|
@@ -157,3 +170,24 @@ def test_exception_message(self) -> None: |
157 | 170 |
|
158 | 171 | # The exception's string representation should match the message |
159 | 172 | assert str(error) == "URL elicitation required" |
| 173 | + |
| 174 | + def test_pickle_roundtrip(self) -> None: |
| 175 | + """Test that URL elicitation errors preserve their payload through pickle.""" |
| 176 | + original = UrlElicitationRequiredError( |
| 177 | + [ |
| 178 | + ElicitRequestURLParams( |
| 179 | + mode="url", |
| 180 | + message="Auth required", |
| 181 | + url="https://example.com/auth", |
| 182 | + elicitationId="test-123", |
| 183 | + ) |
| 184 | + ], |
| 185 | + message="Custom message", |
| 186 | + ) |
| 187 | + |
| 188 | + reconstructed = pickle.loads(pickle.dumps(original)) |
| 189 | + |
| 190 | + assert isinstance(reconstructed, UrlElicitationRequiredError) |
| 191 | + assert reconstructed.error == original.error |
| 192 | + assert reconstructed.elicitations == original.elicitations |
| 193 | + assert str(reconstructed) == "Custom message" |
0 commit comments