Error code reference

Overview

monSQLize uses a unified error code system to identify different types of errors, helping developers accurately identify and handle exceptions. All error objects contain the code attribute, through which the error type can be determined and corresponding processing logic executed.

Common user paths such as configuration, cache, SSH, connection pools, query chains, collection management, transactions, and expression compilation throw error objects with code; error message remains human-readable.

The core runtime uses MonSQLizeError together with the exported ErrorCodes constants. Data Tasks form a separate domain contract: they throw DataTaskJobError, whose discriminated code, phase, and optional collection describe validation, approval, locking, apply, backup, and restore failures. Do not compare Data Task codes with ErrorCodes; handle the two error families explicitly at the boundary.

Data Task error contract

import { DataTaskJobError } from 'monsqlize';

try {
  await dataTasks.apply(job, approval);
} catch (error) {
  if (error instanceof DataTaskJobError) {
    console.error(error.code, error.phase, error.collection);
  }
  throw error;
}
CodeBoundary
INVALID_JOBJob shape or policy validation
IDENTITY_CONFLICTSource/target identity mapping
INDEX_CONFLICTIndex plan conflict
APPROVAL_STALEApproval expired or no longer matches the preview
BACKUP_FAILEDBackup creation or persistence
LOCK_NOT_ACQUIREDLease lock could not be acquired
LOCK_LOSTLease ownership was lost during execution
APPLY_PARTIALApply changed only part of the planned scope
RESTORE_DRIFTRestore preview or approval no longer matches current state
RESTORE_FAILEDRestore execution or read-back verification

See Data Tasks for the preview, approval, apply, backup, and restore workflow.

Core runtime error object structure

{
  message: 'Error description information',
  code: 'ERROR_CODE',      //error code
  details: [...],          //Detailed error message (optional)
  cause: Error             //Original error object (optional)
}

Error handling best practices

User action quick check

Error CodesCommon SourcesPriority Checks
INVALID_CONFIGStructure configuration, connection pool configuration, SSH configuration, Redis/distributed capability configuration, Model schemaDsl runtime configurationRequired fields, field types, URI prefix, authentication field, Redis/SSH runtime configuration, schema-dsl/runtime resolution and API shape
CONNECTION_FAILEDMongoDB connection or memory MongoDB startup failedMongoDB address, network, authentication, service status, error.cause
NOT_CONNECTEDconnect() before accessing the collection, Model, SSH tunnel addressawait msq.connect() first to confirm the connection life cycle
CACHE_UNAVAILABLEThe cache instance is invalid and lacks available cache capabilityWhether the incoming cache implements get/set and whether the Redis configuration is reachable
POOL_NOT_FOUNDThe specified connection pool does not exist or the health checker cannot find the poolWhether the pool name is registered, whether the case is consistent, and whether pools is passed in
INVALID_OPERATIONThe query is executed repeatedly, all connection pools are unavailable, and the transaction status is not allowedWhether to repeat toArray(), pool health status, transaction life cycle
INVALID_ARGUMENTQuery chain parameters, collection management parameters, function cache parametersParameter type, value range, non-empty string/object/array
INVALID_EXPRESSIONExpression DSL or aggregate expression function is illegalFunction name, number of parameters, lambda/object literal format
LOCK_ACQUIRE_FAILED / LOCK_TIMEOUTFailed to obtain business lock or distributed lockLock TTL, number of retries, lock key granularity, Redis status

When you're not sure where to start troubleshooting, start by printing error.code, error.message, error.details, and error.cause.

1. Capture specific errors

import { ErrorCodes } from 'monsqlize';

try {
  await collection('users').insertOne({});
} catch (error) {
  if (error.code === ErrorCodes.DOCUMENT_REQUIRED) {
    console.error('Document parameter is missing, please provide a valid document object');
  } else if (error.code === ErrorCodes.DUPLICATE_KEY) {
    console.error('Document already exists, please check the unique index field');
  } else {
    console.error('Other errors:', error.message);
  }
}

2. Unified error handling

function handleDatabaseError(error) {
  switch (error.code) {
    case ErrorCodes.CONNECTION_FAILED:
      //reconnect
      return reconnect();
    case ErrorCodes.QUERY_TIMEOUT:
      //Record slow query log
      return logSlowQuery(error);
    case ErrorCodes.WRITE_CONFLICT:
      //Retry write operation
      return retryWrite();
    default:
      //Log unknown errors
      logger.error('Unknown error:', error);
      throw error;
  }
}

3. Detailed error information

try {
  await collection('users').insertOne({ name: 'Alice' });
} catch (error) {
  console.log('Error code:', error.code);
  console.log('Error message:', error.message);

  //Some errors contain detailed information
  if (error.details) {
    console.log('Details:', error.details);
  }

  //Part of the error contains the original error
  if (error.cause) {
    console.log('Original error:', error.cause);
  }
}

Error code list

VALIDATION_ERROR

Explanation: Parameter verification failed

Trigger scenario:

  • The parameters provided do not meet the requirements
  • Missing required parameters
  • Wrong parameter type

Example:

try {
  await collection('users').find({ age: 'invalid' });
} catch (error) {
  console.log(error.code); // 'VALIDATION_ERROR'
  console.log(error.details); //Detailed verification error information
}

Handling Suggestions:

  • Check error.details for detailed verification errors
  • Verify input parameters meet API requirements
  • Refer to the API documentation to confirm the correct parameter format

INVALID_ARGUMENT

Explanation: The parameter is invalid

Trigger scenario:

  • The parameter value exceeds the allowed range
  • Illegal parameter combination
  • Incorrect parameter format

Example:

try {
  await collection('users').find({}).limit(-10); //negative limit
} catch (error) {
  console.log(error.code); // 'INVALID_ARGUMENT'
}

Handling Suggestions:

  • Check the type and value range of parameters
  • Confirm whether the parameter combination is legal
  • Refer to the API documentation for parameter constraints

INVALID_COLLECTION_NAME

Explanation: The collection name is invalid

Trigger scenario:

  • Collection name is empty
  • Collection name contains illegal characters
  • The collection name does not comply with MongoDB naming conventions

Example:

try {
  await collection('$invalid.collection'); //Contains illegal characters
} catch (error) {
  console.log(error.code); // 'INVALID_COLLECTION_NAME'
}

Handling Suggestions:

  • Use legal collection names (letters, numbers, underscores)
  • Avoid using reserved characters ($, .)
  • Refer to MongoDB collection naming convention

INVALID_DATABASE_NAME

Explanation: The database name is invalid

Trigger scenario:

  • Database name is empty
  • Database name contains illegal characters
  • The database name does not comply with MongoDB naming conventions

Example:

try {
  await msq.db('invalid/database'); //Contains illegal characters
} catch (error) {
  console.log(error.code); // 'INVALID_DATABASE_NAME'
}

Handling Suggestions:

  • Use a valid database name
  • Avoid using special characters
  • Refer to MongoDB database naming convention

INVALID_CURSOR

Explanation: The cursor is invalid

Trigger scenario:

  • The cursor has expired or been closed
  • Cursor configuration error
  • Inconsistent cursor status

Example:

try {
  const cursor = await collection('users').find({}).cursor();
  await cursor.next();
  //...cursor expired
  await cursor.next(); //This error may be thrown
} catch (error) {
  console.log(error.code); // 'INVALID_CURSOR'
}

Handling Suggestions:

  • Make sure the cursor is not closed or expired
  • Check the cursor life cycle
  • Consider using toArray() or streaming

CURSOR_SORT_MISMATCH

Description: Cursor sorting does not match

Trigger scenario:

  • Sorting fields are inconsistent when cursor is paging
  • Different sorting conditions are used when jumping to the page

Example:

try {
  //The first page is sorted by price
  const page1 = await collection('products')
    .find({})
    .sort({ price: 1 })
    .cursor({ pageSize: 10 });

  //The second page uses name sorting instead - Error!
  await page1.next({ sort: { name: 1 } });
} catch (error) {
  console.log(error.code); // 'CURSOR_SORT_MISMATCH'
}

Handling Suggestions:

  • Ensure that the sorting conditions are consistent when paginating
  • Use the same sort parameters
  • Consider maintaining sorting state at the application layer

JUMP_TOO_FAR

Description: Page jump distance is too far

Trigger scenario:

  • Attempt to jump to a page beyond the reasonable range
  • Skipping too many pages at once

Example:

try {
  const cursor = await collection('users').findPage({}, { pageSize: 10 });
  await cursor.jump(10000); //Jump too far
} catch (error) {
  console.log(error.code); // 'JUMP_TOO_FAR'
}

Handling Suggestions:

  • Reduce page jump distance
  • Use progressive page jumps
  • Consider using normal queries instead of cursors

STREAM_NO_JUMP

Note: Streaming mode does not support page jumps

Trigger scenario:

  • Try page skipping in streaming mode

Example:

try {
  const stream = collection('users').find({}).stream();
  await stream.jump(5); //Streaming mode does not support page jumps
} catch (error) {
  console.log(error.code); // 'STREAM_NO_JUMP'
}

Handling Suggestions:

  • Can only be read sequentially in streaming mode
  • If you need to jump to another page, use cursor mode

STREAM_NO_TOTALS

Note: Streaming mode does not support getting the total number

Trigger scenario:

  • Try to get the total number of records in streaming mode

Example:

try {
  const stream = collection('users').find({}).stream();
  await stream.totalCount(); //Streaming mode is not supported
} catch (error) {
  console.log(error.code); // 'STREAM_NO_TOTALS'
}

Handling Suggestions:

  • For total number, use findAndCount() or count()
  • Streaming mode is only used for data processing and does not calculate totals

STREAM_NO_EXPLAIN

Note: Streaming mode does not support query plans

Trigger scenario:

  • Try to get execution plan in streaming mode

Example:

try {
  const stream = collection('users').find({}).stream();
  await stream.explain(); //Streaming mode is not supported
} catch (error) {
  console.log(error.code); // 'STREAM_NO_EXPLAIN'
}

Handling Suggestions:

  • Use the .explain() method of the chained API
  • Get the execution plan before creating the stream

CONNECTION_TIMEOUT

Description: Connection timeout

Trigger scenario:

  • Database server response timeout
  • Network latency is too high
  • Connection pool wait timeout

Example:

try {
  const msq = new MonSQLize({
    type: 'mongodb',
    config: {
      uri: 'mongodb://slow-server:27017',
      serverSelectionTimeoutMS: 5000
    }
  });
  await msq.connect();
} catch (error) {
  console.log(error.code); // 'CONNECTION_TIMEOUT'
}

Handling Suggestions:

  • Check network connection
  • Add timeout configuration
  • Check database server status
  • Check connection pool configuration

CONNECTION_FAILED

Explanation: Database connection failed

Trigger scenario:

  • The database server is unreachable
  • Connection string error
  • Authentication failed
  • Network error

Example:

try {
  const msq = new MonSQLize({
    type: 'mongodb',
    config: { uri: 'mongodb://invalid-host:27017' }
  });
  await msq.connect();
} catch (error) {
  console.log(error.code); // 'CONNECTION_FAILED'
  console.log(error.cause); //Original MongoDB error
}

Handling Suggestions:

  • Verify connection string format
  • Check database server status
  • Check network connection
  • Verify username and password
  • See error.cause for detailed errors

NOT_CONNECTED

Description: The database is not connected (v1.3.0+)

Trigger scenario:

  • Use pool() / use() / scopedCollection() / scopedModel() before calling connect()

Example:

const msq = new MonSQLize({ uri: '...' });
//await msq.connect() not called
try {
  msq.use('billing').collection('invoices'); //Throw
} catch (error) {
  console.log(error.code); // 'NOT_CONNECTED'
}

Handling Suggestions:

  • Make sure to call await msq.connect() before using any data access method

NO_POOL_MANAGER

Note: Multiple connection pool manager (v1.3.0+) is not configured

Trigger scenario:

  • The MonSQLize constructor did not pass in the pools configuration when calling pool()

Example:

const msq = new MonSQLize({ uri: 'mongodb://localhost:27017' }); // No pools
await msq.connect();
try {
  msq.pool('cn'); //Throw
} catch (error) {
  console.log(error.code); // 'NO_POOL_MANAGER'
}

Handling Suggestions:

  • Configure the pools option in the constructor, or use use() to switch databases (single pool and multiple database scenarios)

POOL_NOT_FOUND

Description: The specified connection pool does not exist (v1.3.0+)

Trigger scenario:

  • poolName of pool(poolName) is not registered in ConnectionPoolManager

Example:

try {
  msq.pool('missing-pool'); //Throw
} catch (error) {
  console.log(error.code);      // 'POOL_NOT_FOUND'
  console.log(error.available); //['cn', 'eu'] — List of currently available connection pools
}

Handling Suggestions:

  • Check the error.available field to confirm available connection pool names
  • Confirm that poolName is exactly the same as the name when initialized (case sensitive)

MODEL_NOT_DEFINED

Description: The specified Model is not registered (v1.3.0+)

Trigger scenario:

  • pool().model(key) or key of scopedModel(key) is not registered to the Model registry

Example:

try {
  msq.pool('cn').model('NonExistentModel'); //Throw
} catch (error) {
  console.log(error.code); // 'MODEL_NOT_DEFINED'
}

Handling Suggestions:

  • Confirm that the Model file has been loaded correctly (check models.path configuration)
  • Confirm that the key string is consistent with key (or name) in the Model definition

CONNECTION_CLOSED

Description: The connection has been closed

Trigger scenario:

  • Perform operations on a closed connection
  • Connection pool is closed
  • The server actively closes the connection

Example:

try {
  await msq.close();
  await collection('users').find({}); //connection closed
} catch (error) {
  console.log(error.code); // 'CONNECTION_CLOSED'
}

Handling Suggestions:

  • Check connection status
  • Re-establish connection
  • Avoid performing actions after shutdown

Database operation error (Database)

DATABASE_ERROR

Explanation: Generic database error

Trigger scenario:

  • Uncategorized error returned by MongoDB driver
  • Database internal error
  • Other database related issues

Example:

try {
  await collection('users').find({ $invalidOp: true });
} catch (error) {
  console.log(error.code); // 'DATABASE_ERROR'
  console.log(error.cause); //Original MongoDB error
}

Handling Suggestions:

  • See error.cause for the original error
  • Check query syntax
  • Check out the MongoDB documentation

QUERY_TIMEOUT

Description: Query timeout

Trigger scenario:

  • Query execution time exceeds maxTimeMS configuration
  • Slow queries result in timeouts

Example:

try {
  await collection('users').find(
    { age: { $gt: 18 } },
    { maxTimeMS: 1000 } //1 second timeout
  );
} catch (error) {
  console.log(error.code); // 'QUERY_TIMEOUT'
}

Handling Suggestions:

  • Optimize query conditions
  • Create appropriate indexes
  • Increase maxTimeMS value
  • Analyze performance using query plans

CACHE_ERROR

Description: Cache operation error

Trigger scenario:

  • Cache read and write failed
  • Cache serialization/deserialization errors
  • Cache configuration error

Example:

try {
  await collection('users').find({}).cache(60000);
  //Cache system failure
} catch (error) {
  console.log(error.code); // 'CACHE_ERROR'
}

Handling Suggestions:

  • Check cache configuration
  • View cache service status (such as Redis)
  • Consider downgrading to not using caching
  • Check if the data is serializable

CACHE_TIMEOUT

Description: Cache operation timed out

Trigger scenario:

  • Cache read timeout
  • cache write timeout
  • The cache service responds slowly

Example:

try {
  await collection('users').find({}).cache(60000);
  //Redis response timeout
} catch (error) {
  console.log(error.code); // 'CACHE_TIMEOUT'
}

Handling Suggestions:

  • Check cache service status
  • Add timeout configuration
  • Consider downgrading to not using caching

INVALID_CONFIG

Explanation: Invalid configuration

Trigger scenario:

  • Configuration parameter error
  • Missing required configuration items
  • Configuration format is incorrect
  • Model schemaDsl runtime cannot resolve schema-dsl/runtime, exposes an incompatible API shape, or receives invalid runtime options

Example:

try {
  const msq = new MonSQLize({
    type: 'mongodb',
    config: { /* missing uri */ }
  });
} catch (error) {
  console.log(error.code); // 'INVALID_CONFIG'
}

Handling Suggestions:

  • Check configuration parameters
  • Refer to documentation to confirm required configuration
  • Verify configuration format
  • For Model schema validation, check bundled dependency installation, package-manager pruning, runtime module resolution, and the schemaDsl runtime/options/extensions configuration

UNSUPPORTED_DATABASE

Description: Unsupported database type

Trigger scenario:

  • An unsupported database type was specified
  • Database version is incompatible

Example:

try {
  const msq = new MonSQLize({
    type: 'mysql', //Not supported
    config: { /* ... */ }
  });
} catch (error) {
  console.log(error.code); // 'UNSUPPORTED_DATABASE'
}

Handling Suggestions:

  • Use supported database types (currently MongoDB only)
  • Check database version compatibility

Write Operations Error (Write Operations)

WRITE_ERROR

Explanation: Generic write operation error

Trigger scenario:

  • The write operation failed to execute
  • Server refuses write
  • Other write related errors

Example:

try {
  await collection('users').insertOne({ _id: 'duplicate' });
  await collection('users').insertOne({ _id: 'duplicate' });
} catch (error) {
  console.log(error.code); //Probably 'WRITE_ERROR'
  console.log(error.cause); //Original MongoDB error
}

Handling Suggestions:

  • See error.cause for detailed errors
  • Check write permission
  • Verify data format

DOCUMENT_REQUIRED

Explanation: Missing document parameter

Trigger scenario:

  • insertOne No documentation provided
  • The document provided is null or undefined

Example:

try {
  await collection('users').insertOne(); //missing documentation
} catch (error) {
  console.log(error.code); // 'DOCUMENT_REQUIRED'
}

Handling Suggestions:

  • Provide a valid document object
  • Check if the document parameter is null or undefined

DOCUMENTS_REQUIRED

Explanation: Missing document array parameter

Trigger scenario:

  • insertMany No document array provided
  • The provided document array is empty

Example:

try {
  await collection('users').insertMany([]); //empty array
} catch (error) {
  console.log(error.code); // 'DOCUMENTS_REQUIRED'
}

Handling Suggestions:

  • Provide at least one document
  • Verify that the document array is not empty

DUPLICATE_KEY

Description: Unique key conflict

Trigger scenario:

  • Insert duplicate _id
  • Violation of unique index constraint

Example:

try {
  await collection('users').insertOne({ _id: 1, name: 'Alice' });
  await collection('users').insertOne({ _id: 1, name: 'Bob' }); //Repeat
} catch (error) {
  console.log(error.code); // 'DUPLICATE_KEY'
  console.log(error.details); //Contains duplicate key information
}

Handling Suggestions:

  • Check unique index fields
  • Use the upsert option of updateOne
  • Catch and handle duplicate errors

WRITE_CONFLICT

Description: Write conflict

Trigger scenario:

  • Concurrent write conflicts
  • Transaction conflicts
  • Optimistic lock conflict

Example:

try {
  //Two concurrent transactions modify the same document
  await msq.withTransaction(async (session) => {
    await collection('users').updateOne(
      { _id: 1 },
      { $inc: { balance: 100 } },
      { session }
    );
  });
} catch (error) {
  console.log(error.code); // 'WRITE_CONFLICT'
}

Handling Suggestions:

  • Retry the write operation
  • Use transaction isolation levels
  • Implement optimistic locking mechanism

LOCK_ACQUIRE_FAILED

Explanation: Lock acquisition failed

Trigger scenario:

  • The distributed lock is already held by another process
  • Lock service is unavailable
  • Lock configuration error

Example:

try {
  const lock = await msq.acquireLock('user:123', { timeout: 5000 });
} catch (error) {
  console.log(error.code); // 'LOCK_ACQUIRE_FAILED'
}

Handling Suggestions:

  • Wait for the lock to be released and try again
  • Check lock service status (such as Redis)
  • Implement lock timeout and retry mechanism
  • Consider using a shorter lock timeout

LOCK_TIMEOUT

Description: Lock wait timeout

Trigger scenario:

  • Waiting for lock for longer than configured timeout
  • Other processes hold locks for a long time

Example:

try {
  const lock = await msq.acquireLock('resource:1', {
    timeout: 3000,
    waitTimeout: 10000
  });
} catch (error) {
  console.log(error.code); // 'LOCK_TIMEOUT'
}

Handling Suggestions:

  • Increase wait timeout
  • Check lock holder status
  • Implement the forced release mechanism of locks
  • Optimize business logic to reduce lock holding time

Quick index of error codes

Error codeCategoryDescription
VALIDATION_ERRORVerificationParameter verification failed
INVALID_ARGUMENTValidationInvalid parameter
INVALID_COLLECTION_NAMEValidationInvalid collection name
INVALID_DATABASE_NAMEValidationInvalid database name
INVALID_EXPRESSIONExpressionInvalid expression DSL
INVALID_OPERATIONOperation statusThe current status does not allow this operation
INVALID_CURSORCursorInvalid cursor
INVALID_PAGINATIONPagingInvalid paging parameter or cursor
CURSOR_SORT_MISMATCHCursorCursor sort mismatch
JUMP_TOO_FARPagingPage jump distance is too far
STREAM_NO_JUMPPagingStreaming mode does not support page jumps
STREAM_NO_TOTALSPagingStreaming mode does not support getting the total number
STREAM_NO_EXPLAINPaginationQuery plan is not supported in streaming mode
CONNECTION_TIMEOUTConnectionConnection timeout
CONNECTION_FAILEDConnectionConnection failed
NOT_CONNECTEDConnectedNot connected yet
CONNECTION_CLOSEDConnectionConnection closed
NO_POOL_MANAGERConnection poolNo connection pool manager configured
POOL_NOT_FOUNDConnection poolThe specified connection pool does not exist
DATABASE_ERRORDatabaseGeneral database error
QUERY_TIMEOUTDatabaseQuery timeout
MANAGEMENT_OPERATION_FAILEDManagement OperationsIndex, bookmark, or collection management operation failed
CACHE_ERRORCacheCache operation error
CACHE_TIMEOUTCacheCache operation timed out
CACHE_UNAVAILABLECachingCaching capability is not available
INVALID_CONFIGConfigurationInvalid configuration
UNSUPPORTED_DATABASEConfigurationUnsupported database type
WRITE_ERRORWrite operationGeneric write operation error
DOCUMENT_REQUIREDWrite operationMissing document parameter
DOCUMENTS_REQUIREDWrite operationMissing document array parameter
DUPLICATE_KEYWrite operationUnique key conflict
WRITE_CONFLICTWrite operationWrite conflict
LOCK_ACQUIRE_FAILEDLockLock acquisition failed 🆕 v1.4.0
LOCK_TIMEOUTLockLock wait timeout 🆕 v1.4.0

FAQ

import { ErrorCodes } from 'monsqlize';

const DATABASE_ERRORS = [
  ErrorCodes.DATABASE_ERROR,
  ErrorCodes.QUERY_TIMEOUT,
  ErrorCodes.CONNECTION_FAILED,
  ErrorCodes.CONNECTION_TIMEOUT,
  ErrorCodes.CONNECTION_CLOSED
];

try {
  await collection('users').find({});
} catch (error) {
  if (DATABASE_ERRORS.includes(error.code)) {
    console.error('Database error:', error.message);
  }
}

How to implement error retry mechanism?

async function retryOnError(fn, retries = 3) {
  const RETRYABLE_ERRORS = [
    ErrorCodes.CONNECTION_TIMEOUT,
    ErrorCodes.QUERY_TIMEOUT,
    ErrorCodes.WRITE_CONFLICT
  ];

  for (let i = 0; i < retries; i++) {
    try {
      return await fn();
    } catch (error) {
      if (RETRYABLE_ERRORS.includes(error.code) && i < retries - 1) {
        await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
        continue;
      }
      throw error;
    }
  }
}

//Usage example
await retryOnError(async () => {
  await collection('users').insertOne({ name: 'Alice' });
});

Error logging best practices

function logError(error, context = {}) {
  const logData = {
    code: error.code,
    message: error.message,
    timestamp: new Date().toISOString(),
    ...context
  };

  if (error.details) {
    logData.details = error.details;
  }

  if (error.cause) {
    logData.cause = {
      name: error.cause.name,
      message: error.cause.message,
      stack: error.cause.stack
    };
  }

  //Select log level based on error type
  if (error.code === ErrorCodes.VALIDATION_ERROR) {
    logger.warn(logData);
  } else if (error.code === ErrorCodes.CONNECTION_FAILED) {
    logger.error(logData);
  } else {
    logger.info(logData);
  }
}

References