Profiles·Public

redis

semver>=5.0.0 <7.0.0postconditions28functions27last verified2026-06-23coverage score100%

Postconditions — what we check

  • createClient · missing-error-listener
    error
    WhencreateClient() called without .on('error', handler) registered
    Required handlingMUST call client.on('error', handler) immediately after createClient(). Handler should log error details and optionally trigger reconnection logic or graceful shutdown.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • connect · connect-no-error-handling
    error
    Whenclient.connect() called without try-catch or .catch() handler
    ThrowsConnection errors (ECONNREFUSED, ETIMEDOUT, ECONNRESET, EAI_AGAIN)
    Required handlingMUST wrap await client.connect() in try-catch block. Catch block should check error.code and implement retry logic with exponential backoff for recoverable errors. Non-recoverable errors should trigger graceful shutdown or fallback mode.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • get · get-no-error-handling
    error
    Whenclient.get() called without try-catch or .catch() handler
    ThrowsConnection errors, timeout errors, or WRONGTYPE errors
    Required handlingMUST wrap await client.get() in try-catch block. For connection errors, implement graceful degradation (fallback to database). For WRONGTYPE errors, fix data schema. For timeout errors, retry with backoff or return cached/default value.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • set · set-no-error-handling
    error
    Whenclient.set() called without try-catch or .catch() handler
    ThrowsConnection errors, timeout errors, or command errors
    Required handlingMUST wrap await client.set() in try-catch block. For connection errors, consider queueing write for retry. For critical writes, re-throw error to caller. For non-critical cache writes, log error and continue without cache.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • del · del-no-error-handling
    error
    Whenclient.del() called without try-catch or .catch() handler
    ThrowsConnection errors or timeout errors
    Required handlingMUST wrap await client.del() in try-catch block. For connection errors, log error and decide whether to retry, fail operation, or continue. Critical deletes should re-throw error to caller for proper handling.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • hSet · hset-no-error-handling
    error
    Whenclient.hSet() called without try-catch or .catch() handler
    ThrowsErrorReply (WRONGTYPE when key exists as non-hash), connection errors (ECONNREFUSED, ETIMEDOUT, ECONNRESET, EAI_AGAIN), SocketClosedUnexpectedlyError
    Required handlingMUST wrap await client.hSet() in try-catch. Check err.message.includes('WRONGTYPE') to distinguish type errors from connection errors. Type errors indicate a data schema bug; connection errors may be retried.
    costmediumin prodimmediate exceptionusers seelost datavisibilityvisible
    Sources[1][2]
  • hGet · hget-no-error-handling
    error
    Whenclient.hGet() called without try-catch or .catch() handler
    ThrowsErrorReply (WRONGTYPE if key is not a hash), connection errors (ECONNREFUSED, ETIMEDOUT, ECONNRESET, EAI_AGAIN)
    Required handlingMUST wrap await client.hGet() in try-catch. Return null fallback for missing fields is correct — do not confuse this with thrown errors.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][3]
  • hGetAll · hgetall-no-error-handling
    error
    Whenclient.hGetAll() called without try-catch or .catch() handler
    ThrowsErrorReply (WRONGTYPE if key is not a hash), connection errors (ECONNREFUSED, ETIMEDOUT, ECONNRESET, EAI_AGAIN)
    Required handlingMUST wrap in try-catch. Also check if the returned object is empty ({}) to detect missing sessions/profiles — returning {} is not an error but often indicates "not found" semantics.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][4]
  • incr · incr-no-error-handling
    error
    Whenclient.incr() called without try-catch or .catch() handler
    ThrowsErrorReply ("ERR value is not an integer or out of range") when key holds a non-integer string; connection errors (ECONNREFUSED, ETIMEDOUT)
    Required handlingMUST wrap await client.incr() in try-catch. Check err.message for "not an integer" to distinguish type errors (data schema bug) from connection errors (retriable).
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][5]
  • incrBy · incrby-no-error-handling
    error
    Whenclient.incrBy() called without try-catch or .catch() handler
    ThrowsErrorReply ("ERR value is not an integer or out of range") when key holds a non-integer; connection errors (ECONNREFUSED, ETIMEDOUT)
    Required handlingMUST wrap await client.incrBy() in try-catch. Same handling as incr().
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][6]
  • expire · expire-no-error-handling
    error
    Whenclient.expire() called without try-catch or .catch() handler
    ThrowsConnection errors (ECONNREFUSED, ETIMEDOUT, ECONNRESET, EAI_AGAIN); ErrorReply on invalid argument types
    Required handlingMUST wrap await client.expire() in try-catch. Prefer atomic client.set(key, value, {EX: ttl}) to avoid the set-then-expire race condition entirely. If separate expire() is required, log and alert on failure — persistent keys are a security and memory risk.
    costmediumin prodimmediate exceptionusers seedegraded performancevisibilitysilent
    Sources[1][7]
  • exists · exists-no-error-handling
    error
    Whenclient.exists() called without try-catch or .catch() handler
    ThrowsConnection errors (ECONNREFUSED, ETIMEDOUT, ECONNRESET, EAI_AGAIN)
    Required handlingMUST wrap await client.exists() in try-catch. Distinguish connection errors from logic errors. For cache-pattern guards, fail safe (treat as "not exists" and proceed to authoritative source).
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • lPush · lpush-no-error-handling
    error
    Whenclient.lPush() called without try-catch or .catch() handler
    ThrowsErrorReply (WRONGTYPE if key is not a list), connection errors (ECONNREFUSED, ETIMEDOUT, ECONNRESET, EAI_AGAIN)
    Required handlingMUST wrap await client.lPush() in try-catch. For queue patterns, re-throw so callers can handle job failure. Check err.message.includes('WRONGTYPE') to detect key type collisions.
    costmediumin prodimmediate exceptionusers seelost datavisibilityvisible
    Sources[1][8]
  • lRange · lrange-no-error-handling
    error
    Whenclient.lRange() called without try-catch or .catch() handler
    ThrowsErrorReply (WRONGTYPE if key is not a list), connection errors (ECONNREFUSED, ETIMEDOUT, ECONNRESET, EAI_AGAIN)
    Required handlingMUST wrap await client.lRange() in try-catch. An empty array is a valid result, not an error condition. Check for ErrorReply type to distinguish Redis server errors from connection errors.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][9]
  • sAdd · sadd-no-error-handling
    error
    Whenclient.sAdd() called without try-catch or .catch() handler
    ThrowsErrorReply (WRONGTYPE if key is not a set), connection errors (ECONNREFUSED, ETIMEDOUT, ECONNRESET, EAI_AGAIN)
    Required handlingMUST wrap await client.sAdd() in try-catch. For deduplication, re-throw on error to prevent silent data loss. Log WRONGTYPE errors — they indicate a key namespace collision that requires investigation.
    costmediumin prodimmediate exceptionusers seelost datavisibilityvisible
    Sources[1][10]
  • sMembers · smembers-no-error-handling
    error
    Whenclient.sMembers() called without try-catch or .catch() handler
    ThrowsErrorReply (WRONGTYPE if key is not a set), connection errors (ECONNREFUSED, ETIMEDOUT, ECONNRESET, EAI_AGAIN)
    Required handlingMUST wrap await client.sMembers() in try-catch. An empty Set is a valid result. WRONGTYPE errors indicate data schema problems requiring code investigation.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][11]
  • zAdd · zadd-no-error-handling
    error
    Whenclient.zAdd() called without try-catch or .catch() handler
    ThrowsErrorReply (WRONGTYPE if key is not a sorted set; "not a float" if score is NaN/Infinity), connection errors (ECONNREFUSED, ETIMEDOUT)
    Required handlingMUST wrap await client.zAdd() in try-catch. Validate score is a finite number before passing to zAdd(). WRONGTYPE indicates a key collision; score errors indicate a computation bug upstream.
    costmediumin prodimmediate exceptionusers seelost datavisibilityvisible
    Sources[1][12]
  • zRange · zrange-no-error-handling
    error
    Whenclient.zRange() called without try-catch or .catch() handler
    ThrowsErrorReply (WRONGTYPE if key is not a sorted set), connection errors (ECONNREFUSED, ETIMEDOUT, ECONNRESET, EAI_AGAIN)
    Required handlingMUST wrap await client.zRange() in try-catch. An empty array is a valid result. Implement fallback for connection errors in leaderboard reads (return cached or empty data rather than throwing to the user).
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][13]
  • exec · multi-exec-watch-error
    error
    Whenclient.watch() was used and the watched key was modified by another client before exec() was called; or client reconnected after WATCH
    ThrowsWatchError (from @redis/client) — thrown from exec() when optimistic locking fails. The transaction was not executed.
    Required handlingMUST wrap exec() in try-catch when WATCH is used. Check err instanceof WatchError to implement retry logic. WatchError means the transaction was not executed — not a partial execution. Retry the full WATCH+MULTI+EXEC sequence.
    costmediumin prodimmediate exceptionusers seelost datavisibilityvisible
    Sources[14][15]
  • exec · multi-exec-connection-error
    error
    WhenConnection is lost or client is closed before exec() completes
    ThrowsSocketClosedUnexpectedlyError, ClientClosedError, or connection system errors (ECONNREFUSED, ECONNRESET)
    Required handlingMUST wrap exec() in try-catch. On connection error, the transaction state is unknown — implement reconciliation logic or re-read state before retrying.
    costmediumin prodimmediate exceptionusers seelost datavisibilityvisible
    Sources[14][1]
  • subscribe · subscribe-no-error-handling
    error
    Whenclient.subscribe() called without try-catch or .catch() handler
    ThrowsClientClosedError (if client is not connected), connection errors (ECONNREFUSED, ETIMEDOUT, ECONNRESET) on network failure during subscription
    Required handlingMUST wrap await client.subscribe() in try-catch for connection failure. The client .on('error') listener handles ongoing connection errors after subscription. Both patterns are required: try-catch for subscribe() AND .on('error') on client.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][16]
  • publish · publish-no-error-handling
    error
    Whenclient.publish() called without try-catch or .catch() handler
    ThrowsConnection errors (ECONNREFUSED, ETIMEDOUT, ECONNRESET, EAI_AGAIN); ClientClosedError if client is disconnected
    Required handlingMUST wrap await client.publish() in try-catch. A return value of 0 is NOT an error — do not throw or retry based on the count alone. Only throw on connection errors or when guaranteed delivery is required (use a different pattern such as streams for guaranteed delivery).
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][17]
  • quit · quit-no-error-handling
    warning
    Whenclient.quit() called without try-catch or .catch() handler
    ThrowsConnection errors if the connection is already closed or lost before QUIT completes; SocketClosedUnexpectedlyError
    Required handlingSHOULD wrap await client.quit() in try-catch in shutdown handlers. Errors during quit() can be logged and swallowed — the connection is being torn down anyway. Use `client.quit().catch(err => logger.warn('Redis quit error', err))` pattern.
    costlowin prodimmediate exceptionusers seedegraded performancevisibilityvisible
    Sources[1][18]
  • close · close-no-error-handling
    warning
    Whenclient.close() called without try-catch or .catch() handler
    ThrowsClientClosedError if close() is called twice; connection-layer errors (ECONNRESET, ETIMEDOUT) if the socket dies during the graceful drain; unhandled promise rejection on any of the above
    Required handlingSHOULD wrap await client.close() in try-catch in shutdown handlers. Errors during close() can be logged and swallowed — the connection is being torn down anyway. Use the same pattern as quit(): `client.close().catch(err => logger.warn('Redis close error', err))`. For graceful shutdown sequencing, await close() before terminating the process so pending commands flush.
    costlowin prodimmediate exceptionusers seedegraded performancevisibilityvisible
    Sources[19][1]
  • watch · watch-no-error-handling
    error
    Whenclient.watch() called without try-catch or .catch() handler
    ThrowsConnection-layer errors (ECONNREFUSED, ETIMEDOUT, ECONNRESET, EAI_AGAIN); ClientClosedError if the client was closed before watch() ran
    Required handlingMUST wrap await client.watch() in try-catch. On error, ABORT the entire transaction — do NOT proceed to multi().exec(). The exec() WatchError handler covers the "watched key changed" case; this handler covers the "watch() itself failed" case. Both are required for correct optimistic locking. Pattern: try { await client.watch('counter'); const value = await client.get('counter'); await client.multi().set('counter', String(Number(value) + 1)).exec(); } catch (err) { if (err instanceof WatchError) { /* retry: key changed */ } else { /* abort: watch or exec failed */ } }
    costmediumin prodimmediate exceptionusers seelost datavisibilityvisible
    Sources[14][15]
  • createClientPool · create-client-pool-no-error-handling
    error
    WhencreateClientPool() factory called without a corresponding pool.on('error') listener AND without try-catch on the subsequent pool.connect()
    Throwspool.connect() throws on connection failure (ECONNREFUSED, ETIMEDOUT, DNS failures); pool runtime errors are dispatched as 'error' events on the pool — uncaught events crash the process by default
    Required handlingMUST register pool.on('error', handler) BEFORE calling pool.connect(), and MUST wrap await pool.connect() in try-catch. Pattern mirrors the createClient() / connect() / .on('error') triad — same rules apply.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[19][14]
  • execute · pool-execute-no-error-handling
    error
    Whenpool.execute(callback) called without try-catch or .catch() handler
    ThrowsWatchError (when callback uses WATCH+MULTI and the watched key was modified); any error thrown by the callback itself; connection-layer errors on the isolated client (ECONNREFUSED, ECONNRESET); ClientClosedError if the pool is closed mid-execute
    Required handlingMUST wrap await pool.execute(...) in try-catch. Discriminate by error type: WatchError → retry the callback (the watched key changed, this is the designed retry signal). Other errors → fail the operation and log. The isolated client is returned to the pool regardless of outcome — do NOT attempt to close it inside the callback. Pattern: try { await pool.execute(async (client) => { await client.watch('key'); const v = await client.get('key'); return client.multi().set('key', updated(v)).exec(); }); } catch (err) { if (err instanceof WatchError) { /* retry */ } else { throw err; } }
    costmediumin prodimmediate exceptionusers seelost datavisibilityvisible
    Sources[14]
  • sendCommand · send-command-no-error-handling
    error
    Whenclient.sendCommand() called without try-catch or .catch() handler
    ThrowsErrorReply / SimpleError when Redis returns an error response (WRONGTYPE, NOSCRIPT, READONLY, MOVED, ASK, MASTERDOWN, etc.); connection-layer errors (ECONNREFUSED, ETIMEDOUT, ECONNRESET); ClientClosedError if the client is disconnected; AbortError if an AbortSignal was attached and aborted
    Required handlingMUST wrap await client.sendCommand() in try-catch. Inspect err.name === 'ReplyError' to handle Redis-level errors (WRONGTYPE, NOSCRIPT, etc.) distinctly from connection-layer errors. If using AbortSignal, also handle AbortError. For commands that mutate state, the safe pattern is: catch → log → re-raise so the caller can decide whether to retry or fail the request.
    costmediumin prodimmediate exceptionusers seelost datavisibilitysilent
    Sources[1]

Sources

Every postcondition cites at least one of these. Numbered to match the footnotes above.

  1. [1]redis.io/docs/latesthttps://redis.io/docs/latest/develop/clients/nodejs/error-handling/
  2. [2]redis.io/commands/hsethttps://redis.io/commands/hset/
  3. [3]redis.io/commands/hgethttps://redis.io/commands/hget/
  4. [4]redis.io/commands/hgetallhttps://redis.io/commands/hgetall/
  5. [5]redis.io/commands/incrhttps://redis.io/commands/incr/
  6. [6]redis.io/commands/incrbyhttps://redis.io/commands/incrby/
  7. [7]redis.io/commands/expirehttps://redis.io/commands/expire/
  8. [8]redis.io/commands/lpushhttps://redis.io/commands/lpush/
  9. [9]redis.io/commands/lrangehttps://redis.io/commands/lrange/
  10. [10]redis.io/commands/saddhttps://redis.io/commands/sadd/
  11. [11]redis.io/commands/smembershttps://redis.io/commands/smembers/
  12. [12]redis.io/commands/zaddhttps://redis.io/commands/zadd/
  13. [13]redis.io/commands/zrangehttps://redis.io/commands/zrange/
  14. [14]redis.io/docs/latesthttps://redis.io/docs/latest/develop/clients/nodejs/transpipe/
  15. [15]redis.io/commands/watchhttps://redis.io/commands/watch/
  16. [16]redis.io/commands/subscribehttps://redis.io/commands/subscribe/
  17. [17]redis.io/commands/publishhttps://redis.io/commands/publish/
  18. [18]redis.io/commands/quithttps://redis.io/commands/quit/
  19. [19]github.com/redis/node-redishttps://github.com/redis/node-redis/blob/master/docs/v4-to-v5.md
Need a different package?
Request a profile