Aden
SDK

Error handling

How the SDK surfaces failures, and how to react to them.

The SDK never throws on non-2xx responses — it returns { data, error } so you can branch explicitly.

const { data, error } = await aden.api.v1.tracks({ id: 42 }).get()

if (error) {
    // error.status is the HTTP status code (number)
    // error.value is the parsed JSON body from the server
    switch (error.status) {
        case 401:
            // Token missing or invalid — prompt re-auth
            break
        case 403:
            // Auth succeeded but scope is insufficient
            break
        case 404:
            // Track doesn't exist or isn't visible to this key
            break
        case 429:
            // Rate-limited — back off and retry
            break
        default:
            throw new Error(`Unexpected: ${error.status}`)
    }
    return
}

use(data)

Shape of errors

All error bodies follow:

{ "error": "Unauthorized" }

The global error handler in packages/api/src/index.ts maps unknown errors to 500 { error: <message> } and auth failures to 401 { error: "Unauthorized" }.

Network errors

If the request never reaches the server, error is populated with status: 'FETCH_ERROR' and value is the underlying Error. This is a good place to retry or flip your app to "offline":

const { data, error } = await aden.api.v1.tracks.get()

if (error?.status === 'FETCH_ERROR') {
    showOfflineBanner()
    return
}

Rate limits

429 responses include standard rate-limit headers:

  • X-RateLimit-Limit — maximum requests in the window.
  • X-RateLimit-Remaining — how many you have left.
  • X-RateLimit-Reset — unix epoch (seconds) when the window resets.

A simple retry helper:

async function withBackoff<T>(
    fn: () => Promise<{ data: T | null; error: unknown }>,
    attempts = 3
) {
    for (let i = 0; i < attempts; i++) {
        const result = await fn()
        const err = result.error as { status?: number } | null
        if (err?.status !== 429) return result
        await new Promise((r) => setTimeout(r, 2 ** i * 1000))
    }
    throw new Error('Exhausted retries')
}

On this page