Skip to main content

Error Handling

All API errors throw an UrblockApiError with structured fields.

UrblockApiError

import { UrblockApiError } from "@urblock/sdk";

Properties

PropertyTypeDescription
messagestringHuman-readable error message
typestringError category
codestringMachine-readable error code
statusnumberHTTP status code
paramstring | undefinedThe parameter that caused the error (if applicable)

Error Types

TypeDescription
invalid_request_errorInvalid parameters, resource not found
authentication_errorInvalid or missing API key
authorization_errorInsufficient permissions
api_errorInternal server error
rate_limit_errorRate limit exceeded

Catching Errors

import { Urblock, UrblockApiError } from "@urblock/sdk";

const urblock = new Urblock("sk_test_...");

try {
const token = await urblock.tokens.retrieve("tok_nonexistent");
} catch (err) {
if (err instanceof UrblockApiError) {
console.error(err.type); // "invalid_request_error"
console.error(err.code); // "token_not_found"
console.error(err.message); // "No token found with id tok_nonexistent."
console.error(err.status); // 404
console.error(err.param); // "token_id"
}
}

Handling by Type

try {
await urblock.tokens.create({ /* ... */ });
} catch (err) {
if (err instanceof UrblockApiError) {
switch (err.type) {
case "invalid_request_error":
// Fix the request parameters
console.error(`Invalid param: ${err.param}`);
break;
case "authentication_error":
// Check your API key
console.error("Bad API key");
break;
case "authorization_error":
// Check API key scopes
console.error("Missing permission");
break;
case "rate_limit_error":
// Back off and retry
console.error("Rate limited, retrying...");
break;
case "api_error":
// Server error — retry with backoff
console.error("Server error, retrying...");
break;
}
}
}

Timeout Errors

If a request exceeds the configured timeout (default: 30 seconds), a UrblockApiError is thrown with code request_timeout:

try {
await urblock.tokens.list();
} catch (err) {
if (err instanceof UrblockApiError && err.code === "request_timeout") {
console.error("Request timed out");
// err.status === 408
}
}

Network Errors

Network-level errors (DNS failure, connection refused, etc.) are thrown as standard JavaScript errors, not UrblockApiError. Wrap calls in a generic try/catch to handle both:

try {
await urblock.tokens.list();
} catch (err) {
if (err instanceof UrblockApiError) {
// API returned an error response
} else {
// Network error, DNS failure, etc.
console.error("Network error:", err);
}
}

Retry Strategy

For production applications, implement exponential backoff for retryable errors:

async function withRetry<T>(
fn: () => Promise<T>,
maxRetries = 3,
): Promise<T> {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await fn();
} catch (err) {
if (err instanceof UrblockApiError) {
// Don't retry client errors (4xx) except rate limits
if (err.status < 500 && err.type !== "rate_limit_error") {
throw err;
}
}
if (attempt === maxRetries) throw err;
await new Promise((r) => setTimeout(r, 2 ** attempt * 1000));
}
}
throw new Error("Unreachable");
}

// Usage
const token = await withRetry(() => urblock.tokens.retrieve("tok_abc123"));