Errors
The SDK defines specific error classes for different failure scenarios. All error classes extend the base SurrealError class, allowing you to catch and handle specific error types.
Base Error
SurrealError
Base class for all SDK errors.
Extends: Error
Example:
try {
await db.select(new RecordId('users', 'john'));
} catch (error) {
if (error instanceof SurrealError) {
console.error('SDK error:', error.message);
}
}
Connection Errors
ConnectionUnavailableError
Thrown when attempting an operation without an active connection.
Message: "You must be connected to a SurrealDB instance before performing this operation"
Example:
const db = new Surreal();
try {
await db.select(new Table('users'));
} catch (error) {
if (error instanceof ConnectionUnavailableError) {
console.error('Not connected to database');
await db.connect('ws://localhost:8000');
}
}
HttpConnectionError
Thrown when an HTTP connection fails.
Properties:
status (number) - HTTP status codestatusText (string) - HTTP status textbuffer (ArrayBuffer) - Response buffer
Example:
try {
await db.connect('http://localhost:8000/rpc');
} catch (error) {
if (error instanceof HttpConnectionError) {
console.error(`HTTP ${error.status}: ${error.statusText}`);
}
}
CallTerminatedError
Thrown when a call is terminated because the connection was closed.
Message: "The call has been terminated because the connection was closed"
Example:
try {
const promise = db.query('SELECT SLEEP(10s)');
await db.close();
await promise;
} catch (error) {
if (error instanceof CallTerminatedError) {
console.error('Connection closed during operation');
}
}
UnexpectedConnectionError
Thrown when an unexpected connection error occurs.
Properties:
cause (unknown) - The underlying error cause
Example:
try {
await db.connect('ws://invalid:8000');
} catch (error) {
if (error instanceof UnexpectedConnectionError) {
console.error('Connection error:', error.cause);
}
}
UnsupportedEngineError
Thrown when attempting to use an unsupported or unconfigured engine.
Properties:
engine (string) - The unsupported engine name
Example:
try {
await db.connect('custom://localhost:8000');
} catch (error) {
if (error instanceof UnsupportedEngineError) {
console.error(`Engine "${error.engine}" is not supported`);
}
}
Reconnection Errors
ReconnectExhaustionError
Thrown when reconnect attempts have been exhausted.
Message: "The reconnect attempts have been exhausted"
Example:
db.subscribe('error', (error) => {
if (error instanceof ReconnectExhaustionError) {
console.error('Failed to reconnect after multiple attempts');
}
});
ReconnectIterationError
Thrown when a reconnect iterator fails to iterate.
Message: "The reconnect iterator failed to iterate"
Response Errors
ResponseError
Thrown when a database query fails with an error response.
Properties:
code (number) - Error code from the databasemessage (string) - Error message from the database
Example:
try {
await db.query('INVALID QUERY');
} catch (error) {
if (error instanceof ResponseError) {
console.error(`Database error [${error.code}]: ${error.message}`);
}
}
UnexpectedServerResponseError
Thrown when the server returns an unexpected response format.
Properties:
response (unknown) - The unexpected response received
Example:
try {
await db.query(complexQuery);
} catch (error) {
if (error instanceof UnexpectedServerResponseError) {
console.error('Unexpected response:', error.response);
}
}
Authentication Errors
AuthenticationError
Thrown when authentication fails.
Message: "Authentication did not succeed"
Properties:
cause (unknown) - The underlying error cause
Example:
try {
await db.signin({
username: 'user',
password: 'wrongpassword'
});
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Authentication failed:', error.cause);
}
}
MissingNamespaceDatabaseError
Thrown when a namespace and/or database is required but not selected.
Message: "There is no namespace and/or database selected"
Example:
const db = new Surreal();
await db.connect('ws://localhost:8000');
try {
await db.select(new Table('users'));
} catch (error) {
if (error instanceof MissingNamespaceDatabaseError) {
await db.use({ namespace: 'test', database: 'test' });
}
}
Live Query Errors
LiveSubscriptionError
Thrown when a live subscription fails to listen.
Message: "Live subscription failed to listen"
Properties:
cause (unknown) - The underlying error cause
Example:
try {
const subscription = await db.live(new Table('users'));
} catch (error) {
if (error instanceof LiveSubscriptionError) {
console.error('Live query failed:', error.cause);
}
}
Version Errors
UnsupportedVersionError
Thrown when the connected SurrealDB version is not supported by the SDK.
Properties:
version (string) - The unsupported versionminimum (string) - Minimum supported version (inclusive)maximum (string) - Maximum supported version (exclusive)
Example:
try {
await db.connect('ws://localhost:8000', {
versionCheck: true
});
} catch (error) {
if (error instanceof UnsupportedVersionError) {
console.error(
`Version ${error.version} not supported. ` +
`Requires: >= ${error.minimum} < ${error.maximum}`
);
}
}
Expression Errors
ExpressionError
Thrown when an expression fails to compile or execute.
Example:
try {
const invalid = expr(() => {
throw new Error('Invalid expression');
});
} catch (error) {
if (error instanceof ExpressionError) {
console.error('Expression error:', error.message);
}
}
PublishError
Thrown when one or more event subscribers throw an error during publication.
Properties:
causes (unknown[]) - The errors thrown by subscribersmessage (string) - Summary message including the cause messages
Example:
db.subscribe('auth', () => {
throw new Error('Handler failed');
});
InvalidDateError
Thrown when a parsed date is invalid.
Message: "The provided date is invalid"
Example:
try {
DateTime.parse('not-a-date');
} catch (error) {
if (error instanceof InvalidDateError) {
console.error('Invalid date:', error.message);
}
}
Feature Errors
UnsupportedFeatureError
Thrown when attempting to use a feature not supported by the configured engine.
Properties:
feature (Feature) - The unsupported feature
Example:
try {
await db.api().get('/endpoint');
} catch (error) {
if (error instanceof UnsupportedFeatureError) {
console.error(`Feature "${error.feature.name}" not supported`);
}
}
UnavailableFeatureError
Thrown when attempting to use a feature not available in the connected SurrealDB version.
Properties:
feature (Feature) - The unavailable featureversion (string) - The connected SurrealDB version
Example:
try {
await db.connect('http://localhost:8000/rpc');
await db.live(new Table('users'));
} catch (error) {
if (error instanceof UnavailableFeatureError) {
console.error(`Feature "${error.feature.name}" not available in version ${error.version}`);
}
}
API Errors
UnsuccessfulApiError
Thrown when a user-defined API call fails.
Properties:
path (string) - The API path that was invokedmethod (string) - The HTTP method usedresponse (ApiResponse) - The error response from the API (includes body?, headers?, status?)message (string) - Human-readable message (inherited from Error; includes path, method, and status)
Example:
try {
await db.api().get('/users/999');
} catch (error) {
if (error instanceof UnsuccessfulApiError) {
console.error(`API error: ${error.message}`);
console.error(`Status: ${error.response.status}`);
}
}
Session Errors
InvalidSessionError
Thrown when attempting to use an invalid or disposed session.
Properties:
session (Session) - The invalid session identifier
Example:
const session = await db.newSession();
await session.closeSession();
try {
await session.select(new Table('users'));
} catch (error) {
if (error instanceof InvalidSessionError) {
console.error('Session is no longer valid');
}
}
Error Handling Patterns
Basic Error Handling
try {
const result = await db.select(new Table('users'));
} catch (error) {
if (error instanceof SurrealError) {
console.error('SDK error:', error.message);
} else {
console.error('Unexpected error:', error);
}
}
Specific Error Handling
try {
await db.connect('ws://localhost:8000');
await db.use({ namespace: 'test', database: 'test' });
await db.signin({ username: 'user', password: 'pass' });
} catch (error) {
if (error instanceof ConnectionUnavailableError) {
console.error('Cannot connect to database');
} else if (error instanceof AuthenticationError) {
console.error('Invalid credentials');
} else if (error instanceof UnsupportedVersionError) {
console.error('Database version incompatible');
} else {
console.error('Unknown error:', error);
}
}
Error Recovery
async function executeWithRetry(fn: () => Promise<any>, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
if (error instanceof ConnectionUnavailableError) {
await db.connect('ws://localhost:8000');
continue;
} else if (error instanceof ResponseError && attempt < maxRetries - 1) {
continue;
}
throw error;
}
}
}
const result = await executeWithRetry(() =>
db.select(new Table('users'))
);
Global Error Handler
db.subscribe('error', (error) => {
if (error instanceof ReconnectExhaustionError) {
notifyUser('Connection lost. Please check your network.');
} else if (error instanceof UnexpectedConnectionError) {
logger.error('Unexpected connection error:', error.cause);
}
});
Best Practices
1. Catch Specific Errors
Handle specific error types for better error recovery:
try {
await operation();
} catch (error) {
if (error instanceof AuthenticationError) {
redirectToLogin();
} else if (error instanceof ConnectionUnavailableError) {
showConnectionError();
}
}
try {
await operation();
} catch (error) {
console.error(error);
}
2. Use Type Guards
TypeScript type guards provide better type safety:
function isConnectionError(error: unknown): error is ConnectionUnavailableError {
return error instanceof ConnectionUnavailableError;
}
if (isConnectionError(error)) {
await reconnect();
}
3. Log Error Details
Include error details in logs for debugging:
catch (error) {
if (error instanceof ResponseError) {
logger.error('Query failed', {
code: error.code,
message: error.message,
query: originalQuery
});
}
}
4. Clean Up on Error
Ensure resources are cleaned up even when errors occur:
const session = await db.newSession();
try {
await session.select(new Table('users'));
} finally {
await session.closeSession();
}
See Also
Source: errors.ts