{
  "id": "error-handling",
  "title": "Error handling",
  "url": "https://redis.io/docs/latest/develop/clients/lettuce/error-handling/",
  "summary": "Learn how to handle errors when using Lettuce.",
  "tags": [],
  "last_updated": "2026-07-24T10:52:10-07:00",
  "page_type": "content",
  "content_hash": "e63bd1b5cc298efd7bb8ad445350e51ba91ac0fc36e801b56ff62bf2feed2f22",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "Lettuce uses **unchecked exceptions** to signal errors. Documentation examples\noften focus on the \"happy path\", but production code should catch and handle\nthe exceptions that matter for your workload. This page explains how Lettuce's\nerror handling works and how to apply common error handling patterns.\n\nFor an overview of error types and handling strategies, see\n[Error handling](https://redis.io/docs/latest/develop/clients/error-handling).\nSee also [Production usage](https://redis.io/docs/latest/develop/clients/lettuce/produsage)\nfor more information on connection management, timeouts, and other aspects of\napp reliability."
    },
    {
      "id": "exception-hierarchy",
      "title": "Exception hierarchy",
      "role": "errors",
      "text": "Lettuce organizes its exceptions under `RedisException`, which extends\n`RuntimeException`:\n\n[code example]"
    },
    {
      "id": "key-exceptions",
      "title": "Key exceptions",
      "role": "content",
      "text": "The following exceptions are the most commonly encountered in Lettuce\napplications. See\n[Categories of errors](https://redis.io/docs/latest/develop/clients/error-handling#categories-of-errors)\nfor a more detailed discussion of these errors and their causes.\n\n| Exception | When it occurs | Recoverable | Recommended action |\n|---|---|---|---|\n| `RedisConnectionException` | Connection setup failed or the connection was lost | ✅ | Retry with backoff or fall back |\n| `RedisCommandTimeoutException` | A command exceeded its timeout | ✅ | Retry with backoff and review timeout settings |\n| `RedisCommandExecutionException` | Redis returned an error reply such as `WRONGTYPE` | ❌ | Fix the command, arguments, or data model |\n| `RedisCommandInterruptedException` | A waiting thread was interrupted while waiting for a result | ⚠️ | Restore interrupt status and abort cleanly |"
    },
    {
      "id": "applying-error-handling-patterns",
      "title": "Applying error handling patterns",
      "role": "content",
      "text": "The [Error handling](https://redis.io/docs/latest/develop/clients/error-handling) overview\ndescribes four main patterns. The sections below show how to implement them in\nLettuce:"
    },
    {
      "id": "pattern-1-fail-fast",
      "title": "Pattern 1: Fail fast",
      "role": "content",
      "text": "Catch specific exceptions that represent unrecoverable errors and re-throw them\n(see\n[Pattern 1: Fail fast](https://redis.io/docs/latest/develop/clients/error-handling#pattern-1-fail-fast)\nfor a full description):\n\n[code example]"
    },
    {
      "id": "pattern-2-graceful-degradation",
      "title": "Pattern 2: Graceful degradation",
      "role": "content",
      "text": "Catch temporary connectivity failures and fall back to an alternative (see\n[Pattern 2: Graceful degradation](https://redis.io/docs/latest/develop/clients/error-handling#pattern-2-graceful-degradation)\nfor a full description):\n\n[code example]"
    },
    {
      "id": "pattern-3-retry-with-backoff",
      "title": "Pattern 3: Retry with backoff",
      "role": "content",
      "text": "Retry on temporary errors such as timeouts or disconnections (see\n[Pattern 3: Retry with backoff](https://redis.io/docs/latest/develop/clients/error-handling#pattern-3-retry-with-backoff)\nfor a full description):\n\n[code example]"
    },
    {
      "id": "pattern-4-log-and-continue",
      "title": "Pattern 4: Log and continue",
      "role": "content",
      "text": "Log non-critical cache failures and continue (see\n[Pattern 4: Log and continue](https://redis.io/docs/latest/develop/clients/error-handling#pattern-4-log-and-continue)\nfor a full description):\n\n[code example]"
    },
    {
      "id": "async-and-reactive-error-handling",
      "title": "Async and reactive error handling",
      "role": "content",
      "text": "Lettuce's async and reactive APIs report the same underlying exceptions, but\nthey usually surface them through `CompletionStage` failures or stream errors\ninstead of direct `throw` statements:\n\n[code example]"
    },
    {
      "id": "see-also",
      "title": "See also",
      "role": "related",
      "text": "- [Error handling](https://redis.io/docs/latest/develop/clients/error-handling)\n- [Production usage](https://redis.io/docs/latest/develop/clients/lettuce/produsage)"
    }
  ],
  "examples": [
    {
      "id": "exception-hierarchy-ex0",
      "language": "hierarchy {type=\"exception\"}",
      "code": "\"RedisException\":\n    _meta:\n        description: \"Base class for Lettuce runtime exceptions\"\n    \"RedisConnectionException\":\n    \"RedisCommandTimeoutException\":\n    \"RedisCommandInterruptedException\":\n    \"RedisCommandExecutionException\":\n        \"RedisLoadingException\":\n    \"...\":\n        _meta:\n            ellipsis: true\n            description: \"Other Lettuce exception types\"",
      "section_id": "exception-hierarchy"
    },
    {
      "id": "pattern-1-fail-fast-ex0",
      "language": "java",
      "code": "try {\n    return commands.get(key);\n} catch (RedisCommandExecutionException e) {\n    // This indicates a bug in our code or data model.\n    throw e;\n}",
      "section_id": "pattern-1-fail-fast"
    },
    {
      "id": "pattern-2-graceful-degradation-ex0",
      "language": "java",
      "code": "try {\n    String cachedValue = commands.get(key);\n    if (cachedValue != null) {\n        return cachedValue;\n    }\n} catch (RedisConnectionException e) {\n    logger.warn(\"Cache unavailable, using database\");\n}\n\nreturn database.get(key);",
      "section_id": "pattern-2-graceful-degradation"
    },
    {
      "id": "pattern-3-retry-with-backoff-ex0",
      "language": "java",
      "code": "int maxRetries = 3;\nlong delayMs = 100;\n\nfor (int attempt = 0; attempt < maxRetries; attempt++) {\n    try {\n        return commands.get(key);\n    } catch (RedisConnectionException | RedisCommandTimeoutException e) {\n        if (attempt == maxRetries - 1) {\n            throw e;\n        }\n        try {\n            Thread.sleep(delayMs);\n            delayMs *= 2;  // Exponential backoff\n        } catch (InterruptedException ie) {\n            Thread.currentThread().interrupt();\n            throw new RuntimeException(ie);\n        }\n    }\n}\n\nthrow new IllegalStateException(\"unreachable\");",
      "section_id": "pattern-3-retry-with-backoff"
    },
    {
      "id": "pattern-4-log-and-continue-ex0",
      "language": "java",
      "code": "try {\n    commands.setex(key, 3600, value);\n} catch (RedisConnectionException | RedisCommandTimeoutException e) {\n    logger.warn(\"Failed to cache {}, continuing without cache\", key, e);\n}",
      "section_id": "pattern-4-log-and-continue"
    },
    {
      "id": "async-and-reactive-error-handling-ex0",
      "language": "java",
      "code": "async.get(key).whenComplete((value, error) -> {\n    if (error == null) {\n        use(value);\n        return;\n    }\n\n    Throwable cause = error.getCause() != null ? error.getCause() : error;\n    if (cause instanceof RedisConnectionException) {\n        logger.warn(\"Cache unavailable\");\n        return;\n    }\n\n    throw new RuntimeException(cause);\n});",
      "section_id": "async-and-reactive-error-handling"
    }
  ]
}
