Error Handling¶
All errors in the Khaya SDK are raised as exceptions — never returned as error dicts or status codes. Use standard Python try/except to handle them.
Exception hierarchy¶
Exception
└── APIError # base class for all Khaya errors
├── AuthenticationError # 401 — invalid or missing API key
├── RateLimitError # 429 — too many requests
├── TranslationError # bad input to translate()
├── TTSGenerationError # bad input to synthesize()
└── ASRTranscriptionError # bad input or missing file for transcribe()
All exceptions expose two attributes:
| Attribute | Type | Description |
|---|---|---|
message |
str |
Human-readable error description |
status_code |
int |
HTTP status code (0 for transport errors) |
Catching errors¶
Catch the specific exception you expect¶
from khaya import KhayaClient
from khaya.exceptions import AuthenticationError, RateLimitError, TranslationError, APIError
with KhayaClient(api_key) as khaya:
try:
result = khaya.translate("Hello", "en-tw")
except AuthenticationError:
# Invalid or missing API key — do not retry
print("Check your KHAYA_API_KEY.")
except RateLimitError as e:
# Too many requests — back off and retry
print(f"Rate limited: {e.message}")
except TranslationError as e:
# Bad input — fix the call, do not retry
print(f"Bad input: {e.message}")
except APIError as e:
# Catch-all for unexpected errors
print(f"Unexpected error ({e.status_code}): {e.message}")
Import exceptions from the top-level package¶
All exceptions are available directly from khaya:
from khaya import (
APIError,
AuthenticationError,
RateLimitError,
TranslationError,
TTSGenerationError,
ASRTranscriptionError,
)
Common scenarios¶
Missing API key¶
Raised immediately — no HTTP request is made:
File not found (ASR)¶
try:
khaya.transcribe("missing.wav", "tw")
except ASRTranscriptionError as e:
print(e.message) # "Audio file not found: missing.wav"
Rate limiting¶
The SDK retries automatically on 429 responses (honouring Retry-After if present). If all retries are exhausted, RateLimitError is raised:
try:
result = khaya.translate("Hello", "en-tw")
except RateLimitError as e:
print(f"Still rate limited after retries: {e.message}")
Transport failures¶
Network errors (timeouts, DNS failures) are also retried automatically. After all retries fail, an APIError is raised with status_code=0:
Retry behaviour¶
The SDK retries automatically on transient errors (429, 500, 502, 503, 504, and network errors) using exponential backoff with jitter. By default, 3 attempts are made.
Configure retry behaviour via Settings:
from khaya.config import Settings
from khaya import KhayaClient
config = Settings(api_key=api_key, retry_attempts=5)
client = KhayaClient(api_key=api_key, config=config)
401 errors are never retried.