Handle TypeScript REST errors
Use this procedure to classify an SDK failure and retry a transient, idempotent
read. Prerequisites: a configured MemoryClient and Node.js 22 or later. The
API reference defines the full error mapping.
1. Preserve status and correlation information
Ordinary REST 401/403 responses raise AuthenticationError. Other unsuccessful
HTTP statuses, including 400/404/429/500, raise TransportError, with
statusCode, responseBody and an optional requestId. Quote the request id in
support reports when present; do not log credentials or raw bodies indiscriminately.
ValidationError and NotSupportedError describe selected failures before HTTP.
NotFoundError exists for compatibility but is not the normal REST 404 mapping.
There is no RateLimitError or ValidationError.details.
import { MemoryClient, MemoryError, TransportError } from "@neo4j-labs/agent-memory";
const client = new MemoryClient();
try {
await client.shortTerm.listConversations({ limit: 5 });
} catch (error) {
if (error instanceof MemoryError) {
console.error(error.name, error.message, error.requestId);
}
if (error instanceof TransportError) console.error("status", error.statusCode);
throw error;
} finally { await client.close(); }
Not every error extends MemoryError. Normal request timeouts can propagate a
DOMException named TimeoutError; token providers and response parsing can
also throw raw errors. Fetch TypeError exceptions are wrapped in ConnectionError.
The optional connect() probe differs: it also wraps timeouts and 5xx responses
in ConnectionError. Bulk writes of more than 100 messages raise a plain Error.
2. Retry only a chosen idempotent read
The SDK sends one attempt per request and does not use Retry-After to schedule
retries. The following complete helper retries only a conversation read, only
on connection failures, 429 or 5xx, and at most three attempts. It propagates
unknown/validation/authentication errors immediately and skips the final sleep.
import { ConnectionError, MemoryClient, TransportError } from "@neo4j-labs/agent-memory";
async function readConversation(client: MemoryClient, conversationId: string) {
for (let attempt = 0; ; attempt++) {
try { return await client.shortTerm.getConversation(conversationId); }
catch (error) {
const transient = error instanceof ConnectionError ||
(error instanceof TransportError && error.statusCode !== undefined &&
(error.statusCode === 429 || error.statusCode >= 500));
if (!transient || attempt === 2) throw error;
await new Promise((resolve) => setTimeout(resolve, 250 * 2 ** attempt));
}
}
}
Do not apply this helper to writes such as addMessage, recordStep or
recordToolCall: a response can be lost after a successful write, and retrying
can duplicate data. Choose write recovery separately for your application.
3. Verify the failure path
Use an offline route stub to return the statuses your application handles.
Assert the class/status and attempt count, plus propagation of an unknown error.
The SDK’s test/integration/docs-contract.test.ts checks this documentation’s
HTTP mapping, lack of automatic retries and unsupported hosted methods.
See request logging for optional events.