All errors extend LunosError. HTTP errors are mapped to specific classes for precise handling.
import Lunos, {
RateLimitError,
AuthenticationError,
APIError,
} from "@lunos/sdk";
try {
await client.chat.completions.create({
model: "openai/gpt-4o",
messages: [{ role: "user", content: "Hello" }],
});
} catch (err) {
if (err instanceof RateLimitError) {
// 429 — wait and retry
} else if (err instanceof AuthenticationError) {
// 401 — invalid API key
} else if (err instanceof APIError) {
console.error(`Error ${err.status}: ${err.message}`);
}
}
| Status | Error Class | When It Happens |
|---|---|---|
| 400 | BadRequestError |
Invalid request parameters |
| 401 | AuthenticationError |
Missing/invalid API key |
| 403 | PermissionDeniedError |
Insufficient permissions |
| 404 | NotFoundError |
Endpoint or resource not found |
| 422 | UnprocessableEntityError |
Valid JSON but semantic error |
| 429 | RateLimitError |
Too many requests |
| ≥500 | InternalServerError |
Server-side failure |
| — | APIConnectionError |
Network connectivity issue |
| — | APIConnectionTimeoutError |
Request exceeded timeout |
Transient failures (408, 409, 429, ≥500, and network errors) are automatically retried with exponential backoff. Non-retryable errors (400, 401, 403, 404, 422) fail immediately.
// Disable retries globally
const client = new Lunos({ apiKey: "sk-...", maxRetries: 0 });
// Override per-request
await client.chat.completions.create(
{ model: "openai/gpt-4o", messages: [{ role: "user", content: "Hi" }] },
{ maxRetries: 5, timeout: 120_000 },
);
The SDK uses exponential backoff with the formula:
delay = min(500ms × 2^attempt, 8000ms)
| Attempt | Delay |
|---|---|
| 1st retry | 500ms |
| 2nd retry | 1000ms |
| 3rd retry | 2000ms |
| 4th retry | 4000ms |
| 5th+ retry | 8000ms (max) |
Cancel requests using AbortSignal:
const controller = new AbortController();
// Cancel after 5 seconds
setTimeout(() => controller.abort(), 5000);
try {
await client.chat.completions.create(
{ model: "openai/gpt-4o", messages: [{ role: "user", content: "Hi" }] },
{ signal: controller.signal },
);
} catch (err) {
if (err instanceof APIConnectionTimeoutError) {
console.log("Request was aborted");
}
}
No headings found on this page.
