The JavaScript SDK defines specific error classes for different failure scenarios. All SDK errors extend the base SurrealError class, making it easy to distinguish SDK errors from other JavaScript errors and to handle specific failure types with instanceof checks.
| Error class | Description |
|---|---|
SurrealError | Base class for all SDK errors |
ConnectionUnavailableError | Thrown when operating without an active connection |
AuthenticationError | Thrown when authentication fails |
ResponseError | Thrown when a database query returns an error |
UnsupportedVersionError | Thrown when the SurrealDB version is incompatible |
A complete list of error classes is available in the Errors API reference.
All errors thrown by the SDK are instances of SurrealError. You can use instanceof checks to catch SDK errors broadly, or target specific error classes for fine-grained handling.
import { SurrealError, AuthenticationError, ConnectionUnavailableError } from 'surrealdb'; try { await db.signin({ username: 'user', password: 'pass' }); } catch (error) { if (error instanceof AuthenticationError) { console.error('Invalid credentials'); } else if (error instanceof ConnectionUnavailableError) { console.error('Not connected to a database'); } else if (error instanceof SurrealError) { console.error('SDK error:', error.message); } }
Connection errors occur when the SDK cannot establish or maintain a connection to the database. The most common are ConnectionUnavailableError (thrown when you attempt an operation without a connection) and HttpConnectionError (thrown when an HTTP request fails).
import { ConnectionUnavailableError, HttpConnectionError } from 'surrealdb'; try { await db.connect('ws://localhost:8000'); } catch (error) { if (error instanceof HttpConnectionError) { console.error(`HTTP ${error.status}: ${error.statusText}`); } }
If you attempt to use an engine protocol that has not been registered, the SDK throws an UnsupportedEngineError with the name of the unsupported engine.
import { UnsupportedEngineError } from 'surrealdb'; try { await db.connect('mem://'); } catch (error) { if (error instanceof UnsupportedEngineError) { console.error(`Engine "${error.engine}" is not registered`); } }
An AuthenticationError is thrown when a sign-in or sign-up attempt fails. A MissingNamespaceDatabaseError is thrown when you attempt an operation that requires a namespace and database without having selected one.
import { AuthenticationError, MissingNamespaceDatabaseError } from 'surrealdb'; try { await db.use({ namespace: 'test', database: 'test' }); await db.signin({ username: 'admin', password: 'secret' }); } catch (error) { if (error instanceof MissingNamespaceDatabaseError) { console.error('No namespace or database selected'); } else if (error instanceof AuthenticationError) { console.error('Authentication failed:', error.cause); } }
When a SurrealQL query fails, the SDK throws a ResponseError containing the error code and message from the database.
import { ResponseError } from 'surrealdb'; try { await db.query('INVALID QUERY'); } catch (error) { if (error instanceof ResponseError) { console.error(`Database error [${error.code}]: ${error.message}`); } }
The SDK performs a version check when connecting to a SurrealDB instance by default. If the connected version is outside the supported range, an UnsupportedVersionError is thrown. You can disable this check using the versionCheck option on .connect().
import { UnsupportedVersionError } from 'surrealdb'; try { await db.connect('ws://localhost:8000'); } catch (error) { if (error instanceof UnsupportedVersionError) { console.error( `Version ${error.version} is not supported. ` + `Requires >= ${error.minimum} and < ${error.maximum}` ); } }
Some features are only available with specific engines or SurrealDB versions. An UnsupportedFeatureError is thrown when a feature is not supported by the configured engine, while an UnavailableFeatureError is thrown when the connected SurrealDB version does not support it.
You can proactively check for feature support using the isFeatureSupported() method to avoid these errors entirely.
import { Features, UnsupportedFeatureError } from 'surrealdb'; if (db.isFeatureSupported(Features.LiveQueries)) { const live = await db.live(new Table('users')); }
The SDK emits an error event for errors that occur outside of direct method calls, such as reconnection failures. You can subscribe to these events using the .subscribe() method.
import { ReconnectExhaustionError, UnexpectedConnectionError } from 'surrealdb'; db.subscribe('error', (error) => { if (error instanceof ReconnectExhaustionError) { console.error('All reconnection attempts failed'); } else if (error instanceof UnexpectedConnectionError) { console.error('Connection error:', error.cause); } });
For operations that may fail transiently, you can implement retry logic. Combine specific error checks with a retry loop to handle recoverable failures gracefully.
import { ConnectionUnavailableError, ResponseError } from 'surrealdb'; async function withRetry<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T> { for (let attempt = 0; attempt < maxRetries; attempt++) { try { return await fn(); } catch (error) { if (error instanceof ConnectionUnavailableError) { await db.connect('ws://localhost:8000'); continue; } if (error instanceof ResponseError && attempt < maxRetries - 1) { continue; } throw error; } } throw new Error('Max retries exceeded'); } const users = await withRetry(() => db.select(new Table('users')));