Error Handling
Both SDKs use typed error classes that extend a base OptropicError. Every error includes a machine-readable code, HTTP status, and human-readable message.
Error Hierarchyโ
OptropicError
โโโ AuthenticationError (401 โ invalid or expired API key)
โโโ ForbiddenError (403 โ insufficient permissions) [Python only]
โโโ NotFoundError (404 โ resource not found) [Python only]
โโโ ValidationError (400 โ invalid request body) [Python only]
โโโ InvalidSerialError (400 โ malformed serial)
โโโ InvalidGTINError (400 โ malformed GTIN)
โโโ InvalidCodeError (400 โ malformed code format)
โโโ CodeNotFoundError (404 โ serial not found)
โโโ BatchNotFoundError (404 โ batch not found)
โโโ RevokedCodeError (410 โ asset revoked)
โโโ RateLimitedError (429 โ rate limit exceeded)
โโโ QuotaExceededError (429 โ monthly quota reached)
โโโ NetworkError (0 โ connection failed)
โโโ TimeoutError (0 โ request timed out)
โโโ ServiceUnavailableError (503 โ server temporarily down)
Catching Errorsโ
- TypeScript
- Python
import { OptropicError, RateLimitedError, AuthenticationError } from 'optropic';
try {
const asset = await client.assets.verify('SER-invalid');
} catch (err) {
if (err instanceof RateLimitedError) {
// Back off and retry
console.log(`Rate limited. Retry after: ${err.message}`);
} else if (err instanceof AuthenticationError) {
// Check API key
console.error('Invalid API key');
} else if (err instanceof OptropicError) {
// All other API errors
console.error(`[${err.code}] ${err.message} (HTTP ${err.status})`);
} else {
throw err; // Not an Optropic error
}
}
from optropic import OptropicError, RateLimitError, AuthenticationError
try:
asset = client.assets.verify("SER-invalid")
except RateLimitError as e:
print(f"Rate limited. {e.message}")
except AuthenticationError as e:
print("Invalid API key")
except OptropicError as e:
print(f"[{e.code}] {e.message} (HTTP {e.status})")
Automatic Retriesโ
The SDK automatically retries on transient errors (429, 500, 502, 503, 504) using exponential backoff with jitter:
delay = min(base_delay ร 2^attempt, max_delay) + (delay ร 0.5 ร random())
Default configuration: 3 retries, 1s base delay, 10s max delay. This prevents thundering herd effects when multiple clients retry simultaneously.
Idempotencyโ
POST, PUT, and PATCH requests automatically include an Idempotency-Key header (UUID v4). This means retries are safe โ the server deduplicates requests with the same idempotency key. GET and DELETE requests do not include this header.