Error Handling
The SDK provides typed error classes for precise error handling:
import {
TrixError,
AuthenticationError,
PermissionError,
NotFoundError,
ValidationError,
RateLimitError,
NetworkError,
TimeoutError,
ServerError
} from '@trixdb/client';
try {
await trix.memories.create({ content: '' });
} catch (error) {
if (error instanceof ValidationError) {
console.log('Validation failed:', error.message);
console.log('Field errors:', error.errors);
} else if (error instanceof RateLimitError) {
console.log('Rate limited. Retry after:', error.retryAfter, 'seconds');
} else if (error instanceof AuthenticationError) {
console.log('Invalid API key');
} else if (error instanceof NotFoundError) {
console.log('Resource not found');
} else if (error instanceof PermissionError) {
console.log('Insufficient permissions');
} else if (error instanceof NetworkError) {
console.log('Network error:', error.message);
} else if (error instanceof TimeoutError) {
console.log('Request timed out');
} else if (error instanceof ServerError) {
console.log('Server error:', error.statusCode);
} else if (error instanceof TrixError) {
console.log('Trix error:', error.message);
}
}Error Properties
| Error Type | Properties |
|---|---|
ValidationError | message, errors (field-level errors) |
RateLimitError | message, retryAfter (seconds) |
ServerError | message, statusCode, response |
| All others | message |
Interceptors
Interceptors let you hook into the request/response lifecycle for logging, authentication, or custom logic.
Request Interceptor
const removeInterceptor = trix.addRequestInterceptor((context) => {
console.log(`Request: ${context.method} ${context.url}`);
return {
...context,
headers: {
...context.headers,
'X-Request-ID': generateRequestId()
}
};
});
removeInterceptor();Response Interceptor
trix.addResponseInterceptor((context) => {
console.log(`Response: ${context.status} ${context.statusText}`);
if (context.headers.get('x-response-time') > 1000) {
console.warn('Slow response detected');
}
return context;
});Error Interceptor
trix.addErrorInterceptor((error, request) => {
console.error(`Error on ${request.method} ${request.url}:`, error.message);
errorTracker.captureException(error, {
extra: { request }
});
return error;
});Pagination
List endpoints return paginated responses. Use async iteration for the simplest approach, or handle pagination manually.
Async Iteration (Recommended)
for await (const memory of trix.memories.listAll({ limit: 100 })) {
processMemory(memory);
}
for await (const cluster of trix.clusters.listAll()) { }
for await (const webhook of trix.webhooks.listAll()) { }
for await (const session of trix.agent.listSessionsAll()) { }Manual Pagination
interface PaginatedResponse<T> {
data: T[];
pagination: {
total: number;
page: number;
limit: number;
hasMore: boolean;
};
}
let page = 1;
let hasMore = true;
while (hasMore) {
const response = await trix.memories.list({ page, limit: 100 });
for (const memory of response.data) {
processMemory(memory);
}
hasMore = response.pagination.hasMore;
page++;
}Pagination Helper
import { paginateAll } from '@trixdb/client';
const allMemories = await paginateAll(
(params) => trix.memories.list(params),
{ limit: 100 }
);
console.log(`Total memories: ${allMemories.length}`);Retry & Backoff
The SDK automatically retries failed requests with exponential backoff.
Default Retry Behavior
{
maxRetries: 3,
initialDelay: 1000,
maxDelay: 60000,
backoffMultiplier: 2,
jitter: true
}
// Retryable errors:
// - RateLimitError (429)
// - NetworkError
// - TimeoutError
// - ServerError (5xx)Manual Retry
import { retry } from '@trixdb/client';
const result = await retry(
() => trix.memories.create({ content: 'test' }),
{
maxRetries: 5,
initialDelay: 2000,
maxDelay: 30000
}
);TypeScript Types
The SDK exports all types for full TypeScript support:
import type {
Memory,
MemoryType,
Relationship,
Cluster,
Space,
Session,
Webhook,
Job,
Highlight,
Transcript,
CreateMemoryRequest,
UpdateMemoryRequest,
ListMemoriesRequest,
PaginatedResponse,
TrixConfig,
TrixError,
ValidationError,
RateLimitError,
RequestInterceptor,
ResponseInterceptor,
ErrorInterceptor
} from '@trixdb/client';Memory Type
interface Memory {
id: string;
spaceId: string;
type: 'text' | 'markdown' | 'url' | 'audio';
content: string;
embedding?: number[];
tags?: string[];
metadata?: Record<string, unknown>;
createdAt: string;
updatedAt: string;
transcriptStatus?: 'pending' | 'processing' | 'completed' | 'failed';
}Relationship Type
interface Relationship {
id: string;
sourceId: string;
targetId: string;
relationshipType: string;
weight: number;
metadata?: Record<string, unknown>;
createdAt: string;
updatedAt: string;
}Session Type
interface Session {
id: string;
spaceId?: string;
name?: string;
metadata?: Record<string, unknown>;
startedAt: string;
endedAt?: string;
memoryCount: number;
}Debugging
Enable debug logging to troubleshoot issues:
import { enableDebugLogging, disableDebugLogging } from '@trixdb/client';
enableDebugLogging();
enableDebugLogging((message) => {
console.log(`[Trix ${new Date().toISOString()}] ${message}`);
});
disableDebugLogging();Debug logging outputs request/response details including URLs, headers, and timing information. Sensitive data like API keys is automatically redacted.
Best Practices
1. Use Environment Variables
const trix = Trix.fromEnv();
// TRIX_API_KEY=gdb_your_api_key2. Handle Errors Gracefully
async function safeCreateMemory(content: string) {
try {
return await trix.memories.create({ content });
} catch (error) {
if (error instanceof RateLimitError) {
await sleep(error.retryAfter * 1000);
return await trix.memories.create({ content });
}
if (error instanceof ValidationError) {
console.error('Invalid memory:', error.errors);
return null;
}
throw error;
}
}3. Use Async Iteration for Large Datasets
for await (const memory of trix.memories.listAll()) {
await processMemory(memory);
}
const all = await paginateAll(trix.memories.list);
all.forEach(processMemory);4. Batch Operations When Possible
await trix.memories.bulkCreate([
{ content: 'Memory 1' },
{ content: 'Memory 2' },
{ content: 'Memory 3' }
]);
await trix.memories.create({ content: 'Memory 1' });
await trix.memories.create({ content: 'Memory 2' });
await trix.memories.create({ content: 'Memory 3' });5. Use Spaces for Isolation
const userSpace = await trix.spaces.create({
name: `User ${userId}`,
metadata: { userId }
});
const memories = await trix.memories.list({
spaceId: userSpace.id,
q: 'search query'
});Complete Example
Here's a complete example demonstrating common SDK operations:
import { Trix, ValidationError, RateLimitError } from '@trixdb/client';
async function main() {
const trix = Trix.fromEnv();
try {
const memory1 = await trix.memories.create({
content: 'TypeScript provides static type checking',
tags: ['typescript', 'programming']
});
const memory2 = await trix.memories.create({
content: 'React uses a virtual DOM for efficient updates',
tags: ['react', 'frontend']
});
console.log('Created memories:', memory1.id, memory2.id);
const relationship = await trix.relationships.create(
memory1.id, memory2.id,
{ relationshipType: 'related_to', weight: 0.75 }
);
console.log('Created relationship:', relationship.id);
const cluster = await trix.clusters.create({
name: 'Web Development',
memoryIds: [memory1.id, memory2.id]
});
console.log('Created cluster:', cluster.id);
const similar = await trix.search.similar(memory1.id, {
limit: 5, threshold: 0.5
});
for (const { memory, similarity } of similar.results) {
console.log(` ${similarity.toFixed(2)}: ${memory.content.slice(0, 40)}...`);
}
const context = await trix.graph.getContext({
memoryId: memory1.id, depth: 2
});
console.log('Context includes', context.related.length, 'related memories');
const session = await trix.agent.createSession({ name: 'Learning Session' });
await trix.agent.addSessionMemory(session.id, {
content: 'User is learning about web development',
tags: ['session-note']
});
await trix.agent.endSession(session.id, { consolidate: true });
console.log('Session completed');
await trix.feedback.quick({ memoryId: memory1.id, type: 'thumbs_up' });
console.log('Feedback submitted');
} catch (error) {
if (error instanceof ValidationError) {
console.error('Validation error:', error.errors);
} else if (error instanceof RateLimitError) {
console.error('Rate limited. Retry after:', error.retryAfter);
} else {
throw error;
}
}
}
main().catch(console.error);Next Steps
- C# SDK - If you're working with .NET
- REST API - Direct HTTP access for any language
- Memory Concepts - Understanding memory types
- Agent Integration - Using Trix with AI agents