Documentation Index
Fetch the complete documentation index at: https://docs.velahq.xyz/docs/llms.txt
Use this file to discover all available pages before exploring further.
The Vela SDK uses a typed error hierarchy rooted at VelaError. Every API error response is wrapped in a specific subclass so you can handle different failure modes independently.
Error class hierarchy
VelaError (base)
├── VelaValidationError — 400 Bad Request
├── VelaAuthError — 401 Unauthorized
├── VelaForbiddenError — 403 Forbidden
├── VelaNotFoundError — 404 Not Found
└── VelaRateLimitError — 429 Too Many Requests
Any other 4xx or 5xx response is thrown as the base VelaError.
Basic error handling
import {
VelaError,
VelaAuthError,
VelaForbiddenError,
VelaNotFoundError,
VelaValidationError,
VelaRateLimitError,
} from '@vela-event/sdk';
try {
await client.apps.get('nonexistent-app');
} catch (err) {
if (err instanceof VelaNotFoundError) {
console.error('App not found — check the slug');
} else if (err instanceof VelaAuthError) {
console.error('Invalid or missing client secret');
} else if (err instanceof VelaForbiddenError) {
console.error('This credential does not have access to this resource');
} else if (err instanceof VelaValidationError) {
console.error('Validation failed:', err.message);
} else if (err instanceof VelaRateLimitError) {
console.error('Rate limited — slow down and retry');
} else if (err instanceof VelaError) {
console.error(`Unexpected API error ${err.statusCode}:`, err.message);
} else {
// Not a VelaError — network error, timeout, DNS failure, etc.
throw err;
}
}
Error properties
Every VelaError instance includes:
class VelaError extends Error {
message: string; // Human-readable error message from the API
statusCode: number; // HTTP status code (400, 401, 404, etc.)
error: string; // Error type label, e.g. "Not Found", "Bad Request"
path: string; // The request path that triggered the error
timestamp: string; // ISO-8601 timestamp of when the error occurred
}
Example:
try {
await app.schemas.get('nonexistent.event');
} catch (err) {
if (err instanceof VelaNotFoundError) {
console.log(err.message); // "Schema not found"
console.log(err.statusCode); // 404
console.log(err.error); // "Not Found"
console.log(err.path); // "/v1/apps/order-service/schemas/nonexistent.event"
console.log(err.timestamp); // "2024-06-01T12:00:00.000Z"
}
}
Network errors
Network errors — DNS failures, connection timeouts, connection refused — are not wrapped in VelaError. They propagate as native TypeError or DOMException. This distinction lets you handle transport failures separately from API errors:
try {
await ingest.ingest({ event: 'order.placed', data: {}, level: 'info' });
} catch (err) {
if (err instanceof VelaError) {
// API responded with an error status code
console.error('API error:', err.statusCode, err.message);
} else if (err instanceof TypeError) {
// Network failure — DNS, connection refused, fetch itself threw
console.error('Network error:', err.message);
} else {
// Something else unexpected
throw err;
}
}
Handling validation errors on ingestion
When an event fails schema validation, Vela returns a 400 with a specific message describing which field failed:
import { VelaValidationError } from '@vela-event/sdk';
try {
await ingest.ingest({
event: 'order.placed',
data: { orderId: 'ord_1' }, // missing required field: amountCents
level: 'info',
});
} catch (err) {
if (err instanceof VelaValidationError) {
console.error(err.message);
// "Event validation failed: field 'amountCents' is required"
}
}
Rate limit handling
When you hit a rate limit (429), implement exponential backoff before retrying:
import { VelaRateLimitError } from '@vela-event/sdk';
async function ingestWithRetry(payload: IngestPayload, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await ingest.ingest(payload);
} catch (err) {
if (err instanceof VelaRateLimitError && attempt < maxRetries) {
const delay = Math.pow(2, attempt) * 1000; // 1s, 2s, 4s
console.warn(`Rate limited — retrying in ${delay}ms`);
await new Promise(resolve => setTimeout(resolve, delay));
} else {
throw err;
}
}
}
}
Auth errors
| Error | When it happens | Fix |
|---|
VelaAuthError (401) | Missing credentials, expired or revoked key/secret | Check VELA_API_KEY or VELA_CLIENT_SECRET |
VelaForbiddenError (403) | Valid credentials, wrong scope — e.g. using an API key on a management endpoint | Use the correct credential for the operation |
// Common mistake: using API key (vela_live_...) for management operations
// This throws VelaForbiddenError
const wrongClient = new VelaManagementClient(process.env.VELA_API_KEY!);
// Fix: use VELA_CLIENT_SECRET instead
const correctClient = new VelaManagementClient(process.env.VELA_CLIENT_SECRET!);