Error Handling
All API errors throw an UrblockApiError with structured fields.
UrblockApiError
import { UrblockApiError } from "@urblock/sdk";
Properties
| Property | Type | Description |
|---|---|---|
message | string | Human-readable error message |
type | string | Error category |
code | string | Machine-readable error code |
status | number | HTTP status code |
param | string | undefined | The parameter that caused the error (if applicable) |
Error Types
| Type | Description |
|---|---|
invalid_request_error | Invalid parameters, resource not found |
authentication_error | Invalid or missing API key |
authorization_error | Insufficient permissions |
api_error | Internal server error |
rate_limit_error | Rate 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"));