Error Handling — TypeScript SDK
All errors thrown by FlareClient are instances of FlareError or one of its subclasses. Import them from @zeridion/flare.
Error hierarchy
FlareError
├── AuthError (401 — invalid or missing API key)
├── QuotaError (402 — quota exceeded)
├── NotFoundError (404 — job not found)
├── ConflictError (409 — idempotency conflict)
└── RateLimitError (429 — rate limit exceeded)
Base class — FlareError
class FlareError extends Error {
readonly code: string; // machine-readable error code from the API
readonly requestId: string; // X-Request-Id value for support
readonly statusCode: number; // HTTP status code
}
Subclasses
AuthError (401)
Thrown when the API key is invalid, expired, or missing.
class AuthError extends FlareError {}
QuotaError (402)
Thrown when your account has exceeded its job quota for the billing period.
class QuotaError extends FlareError {}
NotFoundError (404)
Thrown by cancelJob and retryJob when the job ID does not exist. Note: getJob returns null for 404 instead of throwing.
class NotFoundError extends FlareError {}
ConflictError (409)
Thrown when an idempotency key conflict occurs on createJob — a job with that key already exists and was created with different parameters.
Note: cancelJob and retryJob return null on 409 (state conflict) instead of throwing ConflictError.
class ConflictError extends FlareError {}
RateLimitError (429)
Thrown when the rate limit is exceeded. Includes the reset timestamp so you can implement back-off.
class RateLimitError extends FlareError {
readonly limit: number; // X-RateLimit-Limit — always present on 429 (falls back to 0 if the header is absent)
readonly remaining: number; // X-RateLimit-Remaining — always present on 429 (always 0 in practice)
readonly retryAfter?: number; // Unix epoch seconds when the window resets (X-RateLimit-Reset); undefined if the server omits the header
}
limit and remaining are typed non-optional: the SDK guarantees a numeric value (zero when the server-side header is missing). Only retryAfter is optional, since the server may omit X-RateLimit-Reset for some 429 paths.
Catch patterns
Catch all Flare errors
import { FlareError } from "@zeridion/flare";
try {
await flare.createJob({ job_type: "MyJob", payload: {} });
} catch (err) {
if (err instanceof FlareError) {
console.error(`[${err.statusCode}] ${err.code}: ${err.message} (requestId: ${err.requestId})`);
} else {
throw err; // unexpected — rethrow
}
}
Handle specific errors
import {
FlareError,
AuthError,
RateLimitError,
ConflictError,
QuotaError,
} from "@zeridion/flare";
try {
await flare.createJob({ job_type: "MyJob", payload: {} });
} catch (err) {
if (err instanceof RateLimitError) {
const waitMs = ((err.retryAfter ?? 0) * 1000) - Date.now();
console.warn(`Rate limited. Retry in ${Math.ceil(waitMs / 1000)}s`);
await new Promise(r => setTimeout(r, Math.max(waitMs, 0)));
} else if (err instanceof ConflictError) {
console.log("Idempotency hit — job already enqueued");
} else if (err instanceof QuotaError) {
console.error("Monthly job quota exceeded — upgrade your plan");
} else if (err instanceof AuthError) {
console.error("Invalid API key — check FLARE_API_KEY");
} else if (err instanceof FlareError) {
console.error(err.code, err.requestId, err.statusCode);
} else {
throw err;
}
}
Rate-limit aware retry loop
async function enqueueWithRetry(client: FlareClient, req: CreateJobRequest, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await client.createJob(req);
} catch (err) {
if (err instanceof RateLimitError && attempt < maxRetries - 1) {
const waitMs = ((err.retryAfter ?? 0) * 1000) - Date.now();
await new Promise(r => setTimeout(r, Math.max(waitMs, 1000)));
} else {
throw err;
}
}
}
}
Non-throwing return values
Two methods return null instead of throwing on state-conflict responses:
| Method | Returns null when | Throws on |
|---|---|---|
cancelJob(id) | Job is in a non-cancellable state (409) | Job not found (404 → NotFoundError) |
retryJob(id) | Job is not retryable (409) | Job not found (404 → NotFoundError) |
getJob(id) | Job not found (404) | API errors |
See also
- FlareClient — methods and which errors they can throw
- .NET Exceptions reference — equivalent hierarchy for the .NET SDK
- Error handling guide — cross-language patterns