## Summary - Adds `NetworkTransportError` — a new sibling to `UpstreamError` under `ToolExecutionError` — for failures where no complete HTTP response was received from the upstream service (timeouts, connection errors, pool exhaustion, DNS failures, decoding issues, redirect exhaustion) - Routes client-construction bugs (`InvalidURL`, `UnsupportedProtocol`, `MissingSchema`, `SSLError`, `InvalidHeader`, etc.) to existing `FatalToolError` instead of `UpstreamError` - Adds 3 new `ErrorKind` values: `NETWORK_TRANSPORT_RUNTIME_TIMEOUT`, `_UNREACHABLE`, `_UNMAPPED` — operationally distinct telemetry slices matching the UpstreamError pattern - `UpstreamError` is unchanged and reserved for real HTTP responses with status codes Addresses Eric's feedback on #820: the `include_status_code=False` post-init null-out workaround is replaced by a clean class hierarchy where `NetworkTransportError.status_code` is natively `None`. ### Changes | File | What | |---|---| | `arcade-core/errors.py` | 3 new `ErrorKind` values, `NetworkTransportError` class, `is_network_transport_error` helper | | `arcade-tdk/providers/http/error_adapter.py` | Full rewrite of httpx + requests exception routing with 3-way split | | `arcade-tdk/providers/graphql/error_adapter.py` | `TransportConnectionFailed`/`TransportProtocolError` → `NetworkTransportError` | | `arcade-tdk/errors.py`, `arcade-mcp-server/exceptions.py` | Re-exports | | `pyproject.toml` × 3 | Version bumps: core 4.7.0, tdk 3.7.0, mcp-server 1.20.0 | | Tests × 3 | 33 new tests, 3 updated (2659 passed, 0 failures) | ### Exception routing table | Exception | Target | Kind | can_retry | |---|---|---|---| | `httpx.HTTPStatusError`, `requests.HTTPError` (with response) | `UpstreamError` | status-derived | status-derived | | `httpx.TimeoutException`, `requests.Timeout` | `NetworkTransportError` | `TIMEOUT` | ✅ | | `httpx.TransportError`, `requests.ConnectionError` | `NetworkTransportError` | `UNREACHABLE` | ✅ | | `httpx.DecodingError`, `TooManyRedirects`, fallback | `NetworkTransportError` | `UNMAPPED` | varies | | `httpx.InvalidURL`/`UnsupportedProtocol`/`LocalProtocolError`, `requests.MissingSchema`/`SSLError`/etc. | `FatalToolError` | `TOOL_RUNTIME_FATAL` | ❌ | ### Engine companion PR ArcadeAI/monorepo — `feat/network-transport-error-kinds` adds the 3 `ErrorKind` constants to Go schemas + OpenAPI docs. No engine logic changes needed (ErrorKind is a string alias, retry uses `can_retry` flag only, telemetry auto-slices). ## Test plan - [x] 2659 existing tests pass (0 failures) - [x] 33 new routing + class tests added - [x] mypy clean on arcade-core, arcade-tdk - [ ] Verify engine telemetry dashboard auto-surfaces new `NETWORK_TRANSPORT_*` kinds after deploy 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes the error taxonomy and classification helpers used for retries/telemetry, so misclassification could affect operational behavior, but the change is additive and covered by new tests. > > **Overview** > Adds a new error category for outbound request failures that never yield a complete upstream response: `NetworkTransportError` (sibling to `UpstreamError`) plus `ErrorKind.NETWORK_TRANSPORT_RUNTIME_{TIMEOUT,UNREACHABLE,UNMAPPED}` and matching `is_network_transport_error` classification helpers on both `ToolkitError` and the wire-model `ToolCallError`. > > Re-exports `NetworkTransportError` from `arcade-tdk` and `arcade-mcp-server`, bumps package versions (`arcade-core` 4.7.0, `arcade-tdk` 3.7.0, `arcade-mcp-server` 1.20.0) and dependency minimums, and expands `core/test_errors.py` to cover the new kind invariants/defaults and classification behavior. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit d2b89078729c6a67ba42684dc98445352238bc1d. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
111 lines
2.3 KiB
Python
111 lines
2.3 KiB
Python
"""
|
|
MCP Exception Hierarchy
|
|
|
|
Provides domain-specific exceptions for better error handling and debugging.
|
|
"""
|
|
|
|
from arcade_core.errors import (
|
|
ContextRequiredToolError,
|
|
ErrorKind,
|
|
FatalToolError,
|
|
NetworkTransportError,
|
|
RetryableToolError,
|
|
ToolExecutionError,
|
|
ToolRuntimeError,
|
|
UpstreamError,
|
|
UpstreamRateLimitError,
|
|
)
|
|
|
|
__all__ = [
|
|
# Re-exports
|
|
"ErrorKind",
|
|
"FatalToolError",
|
|
"NetworkTransportError",
|
|
"RetryableToolError",
|
|
"ToolExecutionError",
|
|
"ToolRuntimeError",
|
|
"UpstreamError",
|
|
"UpstreamRateLimitError",
|
|
"ContextRequiredToolError",
|
|
# Base exceptions
|
|
"MCPError",
|
|
"MCPRuntimeError",
|
|
# Server exceptions
|
|
"ServerError",
|
|
"SessionError",
|
|
"RequestError",
|
|
"ResponseError",
|
|
"ServerRequestError",
|
|
"LifespanError",
|
|
# Context exceptions
|
|
"MCPContextError",
|
|
"NotFoundError",
|
|
"AuthorizationError",
|
|
"PromptError",
|
|
"ResourceError",
|
|
"TransportError",
|
|
"ProtocolError",
|
|
]
|
|
|
|
|
|
class MCPError(Exception):
|
|
"""Base error for all MCP-related exceptions."""
|
|
|
|
|
|
class MCPRuntimeError(MCPError):
|
|
"""Runtime error for all MCP-related exceptions."""
|
|
|
|
|
|
class ServerError(MCPRuntimeError):
|
|
"""Error in server operations."""
|
|
|
|
|
|
class SessionError(ServerError):
|
|
"""Error in session management"""
|
|
|
|
|
|
class RequestError(ServerError):
|
|
"""Error in request processing from client to server"""
|
|
|
|
|
|
class ResponseError(ServerError):
|
|
"""Error in request processing from server -> client"""
|
|
|
|
|
|
class ServerRequestError(RequestError):
|
|
"""Error in sending request from server -> client initiated by the server"""
|
|
|
|
|
|
class LifespanError(ServerError):
|
|
"""Error in lifespan management."""
|
|
|
|
|
|
class MCPContextError(MCPError):
|
|
"""Error in context management."""
|
|
|
|
|
|
class NotFoundError(MCPContextError):
|
|
"""Requested entity not found."""
|
|
|
|
|
|
class AuthorizationError(MCPContextError):
|
|
"""Authorization failure."""
|
|
|
|
|
|
class PromptError(MCPContextError):
|
|
"""Error in prompt management."""
|
|
|
|
|
|
class ResourceError(MCPContextError):
|
|
"""Error in resource management."""
|
|
|
|
|
|
# Transport and Protocol Errors
|
|
|
|
|
|
class TransportError(MCPRuntimeError):
|
|
"""Error in transport layer (stdio, HTTP, etc)."""
|
|
|
|
|
|
class ProtocolError(MCPRuntimeError):
|
|
"""Error in MCP protocol handling."""
|