SDK — Error handling
Every failure is a typed ApulodiError:
ts
import { ApulodiError } from "@apulodi/sdk";
try {
await apulodi.files.get("file_missing");
} catch (error) {
if (error instanceof ApulodiError) {
error.status; // HTTP status; 0 for network/timeout failures
error.code; // "FILE_NOT_FOUND"
error.message; // human-readable
error.details; // structured extras (validation issues, …)
}
}
Properties
| Property | Type | Meaning |
|---|---|---|
status | number | HTTP status, or 0 when the network/transport failed |
code | string | Stable machine-readable code (see Errors) |
message | string | Human-readable explanation |
details | unknown | Optional structured context (Zod issues, …) |
isClientError | boolean | True for 4xx responses |
isServerError | boolean | True for 5xx responses |
What never leaks
- Your API key — scrubbed (
[REDACTED]) from any error message or body. - Raw provider/database errors — the API converts them to
INTERNAL_ERROR; the SDK re-checks in case a proxy returns something raw. - Internal stack traces — SDK errors carry a clean, stable message.
Network & timeouts
When fetch fails (DNS, connection refused, …) or the request times out, the
SDK still throws ApulodiError with status: 0:
ts
catch (error) {
if (error instanceof ApulodiError) {
if (error.status === 0) {
// NETWORK_ERROR or TIMEOUT — safe to retry
} else if (error.isServerError) {
// 5xx — exponential backoff retry
}
}
}
ts
const apulodi = new Apulodi({
apiKey: process.env.APULODI_API_KEY!,
timeoutMs: 15000, // per-request timeout
});
Retry with idempotency
files.upload() supports an optional Idempotency-Key for retry-safe upload
initialization:
ts
const file = await apulodi.files.upload({
file: data,
fileName: "report.txt",
contentType: "text/plain",
idempotencyKey: crypto.randomUUID(),
});
Repeating the same key returns the same file instead of creating a duplicate.
Next: Guide — Upload from Next.js.