Error Handling Strategy
Relevant source files
The following files were used as context for generating this wiki page:
The StackOne AI SDK implements a centralized error handling strategy built around a specific exception hierarchy. The primary goal is to ensure all SDK-raised errors are catchable via a single base class while providing detailed, actionable diagnostic information from the underlying SaaS connectors and API responses.
Exception Hierarchy
All custom exceptions in the SDK derive from StackOneError. This structure ensures that a single except StackOneError block catches all errors raised by the library, including configuration, loading, and API-related issues.
The diagram above illustrates the inheritance relationship where specific operational errors extend from broader categories, all ultimately rooting in StackOneError.
Sources: stackone_ai/types.py:34-65, CLAUDE.md:120-125
Core Exception Types
| Exception Class | Description |
|---|---|
StackOneError | The base class for all exceptions in the SDK. |
StackOneAPIError | Raised when the StackOne API returns a non-success HTTP status code. It includes the status_code and the response_body. |
ToolsetError | The base class for errors related to tool discovery, configuration, or loading. |
ToolsetConfigError | Raised for invalid configuration parameters, such as out-of-range top_k values in search. |
ToolsetLoadError | Raised when the SDK fails to load tools from the Model Context Protocol (MCP) endpoint. |
Sources: stackone_ai/types.py:34-65, tests/test_fetch_tools.py:612-628
API Error Diagnostics
When the SDK encounters an HTTP error, it raises a StackOneAPIError. The SDK prioritizes the server's own explanation of the failure to make the error message actionable for the user.
Failure Description Logic
The function _describe_api_failure extracts the most relevant message from the response body, looking specifically for keys like message, error, or detail. If the response is not JSON, it captures the first 500 characters of the plain text response.
def _describe_api_failure(exc: httpx.HTTPStatusError, body: Any) -> str:
detail: Any = None
if isinstance(body, dict):
for key in ("message", "error", "detail"):
if isinstance(body.get(key), str):
detail = body[key]
break
status = f"{exc.response.status_code} {exc.response.reason_phrase}".strip()
return f"{status}: {detail}" if detail else f"{status} from {exc.request.url}"
Sources: stackone_ai/tools.py:216-235
Argument Validation
The SDK validates arguments before reaching the network to prevent unnecessary API calls.
- JSON Encoding: If arguments cannot be encoded as JSON (e.g., containing bytes or sets), the SDK raises a
ValueError. - Structure Validation: The SDK raises a
ValueErrorif tool arguments are not provided as a JSON object (dictionary).
Sources: stackone_ai/tools.py:449-455, tests/test_models.py:249-255
MCP Failure Handling
Tool discovery via the Model Context Protocol (MCP) involves streaming HTTP transports and asynchronous task groups. Errors in this flow are often wrapped in ExceptionGroup.
Diagnostic unwrapping
The _describe_mcp_failure utility unwraps ExceptionGroup to find the underlying cause. It converts httpx.HTTPStatusError into a StackOneAPIError while preserving the status code and reason phrase. This prevents "TaskGroup noise" from obscuring the actual failure, such as an expired account link (HTTP 412).
The flow diagram shows how the SDK processes complex asynchronous errors into simplified, actionable exceptions.
Sources: stackone_ai/tools.py:186-213, tests/test_fetch_tools.py:510-530
Framework Integration Adapters
The SDK maps internal errors to framework-specific exceptions when using adapters for LangChain or Pydantic AI.
LangChain Integration
The LangChain adapter catches StackOneError and ValueError and re-raises them as langchain_core.tools.ToolException. This allows LangChain's handle_tool_error logic to catch the exception and potentially feed the error message back to the AI agent for a retry. The adapter manually attaches the status_code and response_body to the ToolException.
Sources: stackone_ai/tools.py:553-577, tests/test_fetch_tools.py:722-735
Pydantic AI Integration
The Pydantic AI adapter catches StackOneError and ValueError and raises a pydantic_ai.exceptions.ModelRetry. This signal instructs the AI agent to attempt the tool call again, using the error message (which includes the server's explanation) as context for correction.
Sources: stackone_ai/tools.py:598-608, tests/test_fetch_tools.py:737-745
Binary and Malformed Content Handling
The SDK distinguishes between JSON API responses and opaque file downloads.
- Content-Type Trust: The SDK uses the
Content-Typeheader to decide between JSON parsing and raw byte return. If the header is missing or indicates a non-JSON type, the SDK returns the raw bytes in acontentkey rather than risking a decoding failure. - Filename Sanitization: When handling file downloads, the SDK extracts filenames from the
Content-Dispositionheader. It reduces these to a safe basename, stripping directory traversal attempts (e.g.,../../) and Unicode format characters to prevent security vulnerabilities.
Sources: stackone_ai/types.py:84-118, stackone_ai/tools.py:428-440, tests/test_tool_calling.py:165-190