Error Model

All errors inherit from RedisSchemaEngineError. Learn about each error type and when to handle them.

Base error class

All errors inherit from RedisSchemaEngineError

Error types

ErrorWhen it's thrown
SchemaValidationErrorAt construction — invalid schema, circular relations, duplicate keys
EntityNotFoundError(Reserved; current API returns null for missing entities)
InvalidOperationErrorWrong call shape, missing confirmation, bad params
RedisConnectionErrorUnderlying Redis network/protocol failure
MemoryLimitErrorHydration exceeded limits.maxMemoryUsagePerOperation
CircuitBreakerOpenErrorOperation rejected because the breaker is OPEN
HydrationDepthExceededErrorRead exceeded limits.maxHydrationDepth

SchemaValidationError

Thrown at cache construction time when the schema is invalid. This includes:

  • Unknown relation target (referencing an entity type that doesn't exist)
  • Circular relations (A → B → A without a clear direction)
  • Duplicate keys (two schemas generating the same Redis key)
  • Invalid field types (using a type not in the allowed set)
  • Reserved field name collision (using __rse_ prefix in your schema)
import { SchemaValidationError } from 'redis-graph-cache';

try {
  const cache = new RedisGraphCache(invalidSchema, config);
} catch (err) {
  if (err instanceof SchemaValidationError) {
    console.error('Schema is invalid:', err.message);
    // Fix the schema and retry
  }
}

InvalidOperationError

Thrown when the operation is malformed or violates safety constraints:

  • Missing confirmation string for clearAllCache
  • Attempting clearAllCache in production without allowProduction
  • Invalid parameters (wrong types, missing required fields)
  • Operation not supported in current configuration
import { InvalidOperationError } from 'redis-graph-cache';

try {
  await cache.clearAllCache({ confirm: 'YES_WIPE_ALL' });
} catch (err) {
  if (err instanceof InvalidOperationError) {
    console.error('Invalid operation:', err.message);
  }
}

RedisConnectionError

Thrown when Redis is unreachable or the connection fails. This can happen due to:

  • Redis server is down
  • Network connectivity issues
  • Authentication failures
  • Protocol errors
  • Connection pool exhaustion
import { RedisConnectionError } from 'redis-graph-cache';

try {
  await cache.writeEntity('post', postData);
} catch (err) {
  if (err instanceof RedisConnectionError) {
    // Serve stale data or fall back to DB
    console.error('Redis connection failed:', err.message);
  }
}

Retry behavior

RedisConnectionError is thrown after the retry budget is exhausted. Transient failures are automatically retried with exponential backoff before this error is surfaced.

CircuitBreakerOpenError

Thrown when the circuit breaker is OPEN and operations are being rejected to prevent cascading failures.

import { CircuitBreakerOpenError } from 'redis-graph-cache';

try {
  await cache.readEntity('post', 1);
} catch (err) {
  if (err instanceof CircuitBreakerOpenError) {
    // Serve stale or fall back to DB
    console.error('Circuit breaker is open:', err.message);
  }
}

Circuit breaker states

The circuit breaker has three states: CLOSED (normal), OPEN (rejecting operations), and HALF_OPEN (probing recovery). Operations fail fast when OPEN to prevent overwhelming a degraded Redis.

HydrationDepthExceededError

Thrown when a read operation exceeds the configured maxHydrationDepth limit. This prevents infinite recursion in case of circular references.

import { HydrationDepthExceededError } from 'redis-graph-cache';

try {
  await cache.readEntity('post', 1);
} catch (err) {
  if (err instanceof HydrationDepthExceededError) {
    // Your relations form a cycle; reduce maxDepth or excludeRelations
    console.error('Hydration depth exceeded:', err.message);
  }
}

Circular references

If your relations form cycles, use excludeRelations or reduce maxDepth to prevent this error. The cache also emits stub objects with $ref fields when it detects cycles during hydration.

MemoryLimitError

Thrown when a read operation would exceed the configured maxMemoryUsagePerOperation limit. This prevents out-of-memory errors when hydrating large datasets.

import { MemoryLimitError } from 'redis-graph-cache';

try {
  await cache.readEntity('post', 1);
} catch (err) {
  if (err instanceof MemoryLimitError) {
    // Reduce hydration depth or use selectiveFields
    console.error('Memory limit exceeded:', err.message);
  }
}

Error handling best practices

Recommended pattern

Wrap cache operations in try-catch blocks and handle errors appropriately for your use case.

import {
  CircuitBreakerOpenError,
  HydrationDepthExceededError,
  RedisConnectionError,
} from 'redis-graph-cache';

async function getPost(id: number) {
  try {
    return await cache.readEntity('post', id);
  } catch (err) {
    if (err instanceof CircuitBreakerOpenError) {
      // Serve stale or fall back to DB
      return await db.posts.findById(id);
    } else if (err instanceof HydrationDepthExceededError) {
      // Retry with reduced depth
      return await cache.readEntity('post', id, { maxDepth: 2 });
    } else if (err instanceof RedisConnectionError) {
      // Log and fall back to DB
      console.error('Redis connection failed:', err.message);
      return await db.posts.findById(id);
    } else {
      // Re-throw unexpected errors
      throw err;
    }
  }
}