Error Handling¶
All exceptions are importable from tango.exceptions.
Exception Hierarchy¶
TangoAPIError
├── TangoAuthError (401 Unauthorized)
├── TangoNotFoundError (404 Not Found)
├── TangoValidationError (400 Bad Request)
├── TangoRateLimitError (429 Too Many Requests)
└── ShapeError
├── ShapeValidationError (invalid field names)
├── ShapeParseError (invalid shape syntax)
├── TypeGenerationError (dynamic type generation failure)
└── ModelInstantiationError (model creation failure)
API Errors¶
TangoAPIError (base)¶
All API errors inherit from this class.
| Attribute | Type | Description |
|---|---|---|
status_code | int \| None | HTTP status code |
response_data | dict | Parsed response body (credentials redacted) |
message | str | Human-readable error message |
from tango import TangoClient
from tango.exceptions import TangoAPIError
client = TangoClient()
try:
resp = client.list_contracts(limit=10)
except TangoAPIError as e:
print(f"API error {e.status_code}: {e.message}")
TangoAuthError (401)¶
Raised when the API key is missing, invalid, or expired.
from tango.exceptions import TangoAuthError
try:
client = TangoClient(api_key="invalid-key")
client.list_contracts(limit=1)
except TangoAuthError:
print("Check your API key")
TangoNotFoundError (404)¶
Raised when a resource doesn't exist.
from tango.exceptions import TangoNotFoundError
try:
entity = client.get_entity("INVALID_UEI")
except TangoNotFoundError:
print("Entity not found")
TangoValidationError (400)¶
Raised for invalid request parameters (bad date format, unknown filter, etc.).
TangoRateLimitError (429)¶
Raised when you exceed rate limits. Includes retry information.
| Attribute | Type | Description |
|---|---|---|
wait_in_seconds | int \| None | Seconds to wait before retrying |
detail | str \| None | Human-readable rate limit message |
limit_type | str \| None | "burst" or "daily" |
import time
from tango.exceptions import TangoRateLimitError
try:
resp = client.list_contracts(limit=10)
except TangoRateLimitError as e:
if e.wait_in_seconds:
print(f"Rate limited ({e.limit_type}). Retrying in {e.wait_in_seconds}s...")
time.sleep(e.wait_in_seconds)
resp = client.list_contracts(limit=10)
Note
The SDK does not include built-in retry or backoff. You are responsible for handling rate limit errors. See the Rate Limits guide for strategies.
Shape Errors¶
These are raised when there's a problem with the response shaping configuration, not the API itself.
ShapeValidationError¶
Raised when a shape string references field names that don't exist on the model.
from tango.exceptions import ShapeValidationError
try:
resp = client.list_contracts(shape="key,piid,nonexistent_field", limit=1)
except ShapeValidationError as e:
print(f"Invalid shape: {e}")
print(f"Shape string: {e.shape}")
ShapeParseError¶
Raised when the shape string has invalid syntax (unbalanced parentheses, etc.).
| Attribute | Type | Description |
|---|---|---|
shape | str | The invalid shape string |
position | int \| None | Character position where parsing failed |
TypeGenerationError¶
Raised when the SDK fails to generate a dynamic TypedDict for a shaped response.
ModelInstantiationError¶
Raised when the SDK fails to create a model instance from API data.
| Attribute | Type | Description |
|---|---|---|
field_name | str \| None | Field that caused the failure |
expected_type | type \| None | Expected Python type |
actual_value | Any | Value that couldn't be coerced |