{
  "id": "error-handling",
  "title": "Error handling",
  "url": "https://redis.io/docs/latest/develop/clients/rust/error-handling/",
  "summary": "Learn how to handle errors when using redis-rs",
  "tags": [],
  "last_updated": "2026-04-01T08:10:08-05:00",
  "page_type": "content",
  "content_hash": "88c5bf5bd9ea01d62e082036a48e3855f3fe7cd38323a6a2493e180520c35334",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "redis-rs uses **Result types** following Rust's idiomatic error handling pattern. Code examples in the documentation often omit error handling for brevity,\nbut it is essential in production code.\nThis page explains how error handling works in redis-rs and how to apply\nsome common error handling patterns. For an overview of error types and handling\nstrategies, see [Error handling]()."
    },
    {
      "id": "error-handling-in-rust",
      "title": "Error handling in Rust",
      "role": "errors",
      "text": "In Rust, functions return errors using the `Result<T, E>` type. You can check for errors explicitly with code like the following:\n\n[code example]"
    },
    {
      "id": "error-types",
      "title": "Error types",
      "role": "errors",
      "text": "redis-rs provides a `RedisError` type with various error kinds. Common error kinds include:\n\n| Error Kind | When it occurs | Recoverable | Recommended action |\n|---|---|---|---|\n| `ErrorKind::Io` | Network or I/O error | ✅ | Retry with backoff or fall back to alternative |\n| `ErrorKind::AuthenticationFailed` | Invalid credentials | ❌ | Fix credentials and fail |\n| `ErrorKind::UnexpectedReturnType` | Type mismatch | ❌ | Fix the command or type conversion |\n| `ErrorKind::Server` | Redis server error response | ⚠️ | Check specific server error; some are retryable |\n| `ErrorKind::Parse` | Failed to parse server response | ❌ | Report as a bug |\n\nSee [Categories of errors]()\nfor a more detailed discussion of these errors and their causes."
    },
    {
      "id": "applying-error-handling-patterns",
      "title": "Applying error handling patterns",
      "role": "content",
      "text": "The [Error handling]() overview\ndescribes four main patterns. The sections below show how to implement them in\nredis-rs:"
    },
    {
      "id": "pattern-1-fail-fast",
      "title": "Pattern 1: Fail fast",
      "role": "content",
      "text": "Return the error immediately if it represents an unrecoverable situation (see\n[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": "Check for specific errors and fall back to an alternative (see\n[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 (see\n[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 errors and continue (see\n[Pattern 4: Log and continue]()\nfor a full description):\n\n[code example]"
    },
    {
      "id": "async-error-handling",
      "title": "Async error handling",
      "role": "content",
      "text": "Error handling works the same way when you use async/await with redis-rs,\nas shown in the example below:\n\n[code example]"
    },
    {
      "id": "see-also",
      "title": "See also",
      "role": "related",
      "text": "- [Error handling]()\n- [redis-rs documentation](https://docs.rs/redis/latest/redis/)"
    }
  ],
  "examples": [
    {
      "id": "error-handling-in-rust-ex0",
      "language": "rust",
      "code": "use redis::Commands;\n\nlet client = redis::Client::open(\"redis://127.0.0.1/\")?;\nlet mut con = client.get_connection()?;\n\nmatch con.get::<_, String>(\"key\") {\n    Ok(value) => println!(\"Value: {}\", value),\n    Err(e) => {\n        // Handle the error\n        eprintln!(\"Error: {}\", e);\n    }\n}",
      "section_id": "error-handling-in-rust"
    },
    {
      "id": "pattern-1-fail-fast-ex0",
      "language": "rust",
      "code": "use redis::{Commands, RedisResult};\n\nfn get_value(con: &mut redis::Connection, key: &str) -> RedisResult<String> {\n    // Using ? operator to propagate errors immediately\n    let value: String = con.get(key)?;\n    Ok(value)\n}",
      "section_id": "pattern-1-fail-fast"
    },
    {
      "id": "pattern-2-graceful-degradation-ex0",
      "language": "rust",
      "code": "use redis::{Commands, ErrorKind};\n\nfn get_with_fallback(\n    con: &mut redis::Connection,\n    key: &str,\n) -> Result<String, Box<dyn std::error::Error>> {\n    match con.get::<_, String>(key) {\n        Ok(value) => Ok(value),\n        Err(e) => {\n            if e.kind() == ErrorKind::Io {\n                // Network error, use fallback\n                log::warn!(\"Cache unavailable, using database\");\n                database_get(key)\n            } else {\n                Err(Box::new(e))\n            }\n        }\n    }\n}",
      "section_id": "pattern-2-graceful-degradation"
    },
    {
      "id": "pattern-3-retry-with-backoff-ex0",
      "language": "rust",
      "code": "use redis::{Commands, ErrorKind};\nuse std::thread;\nuse std::time::Duration;\n\nfn get_with_retry(\n    con: &mut redis::Connection,\n    key: &str,\n    max_attempts: u32,\n) -> redis::RedisResult<String> {\n    let mut delay = Duration::from_millis(100);\n    \n    for attempt in 0..max_attempts {\n        match con.get::<_, String>(key) {\n            Ok(value) => return Ok(value),\n            Err(e) => {\n                if attempt < max_attempts - 1 && e.kind() == ErrorKind::Io {\n                    thread::sleep(delay);\n                    delay *= 2; // Exponential backoff\n                    continue;\n                }\n                return Err(e);\n            }\n        }\n    }\n    \n    unreachable!()\n}",
      "section_id": "pattern-3-retry-with-backoff"
    },
    {
      "id": "pattern-4-log-and-continue-ex0",
      "language": "rust",
      "code": "use redis::{Commands, ErrorKind};\n\nfn cache_value(con: &mut redis::Connection, key: &str, value: &str) {\n    if let Err(e) = con.set_ex::<_, _, _, ()>(key, value, 3600) {\n        if e.kind() == ErrorKind::Io {\n            log::warn!(\"Failed to cache {}, continuing without cache\", key);\n            // Application continues normally\n        } else {\n            log::error!(\"Unexpected error caching {}: {}\", key, e);\n        }\n    }\n}",
      "section_id": "pattern-4-log-and-continue"
    },
    {
      "id": "async-error-handling-ex0",
      "language": "rust",
      "code": "use redis::AsyncCommands;\n\nasync fn get_with_fallback_async(\n    con: &mut redis::aio::MultiplexedConnection,\n    key: &str,\n) -> Result<String, Box<dyn std::error::Error>> {\n    match con.get::<_, String>(key).await {\n        Ok(value) => Ok(value),\n        Err(e) => {\n            if e.kind() == redis::ErrorKind::Io {\n                log::warn!(\"Cache unavailable\");\n                database_get_async(key).await\n            } else {\n                Err(Box::new(e))\n            }\n        }\n    }\n}",
      "section_id": "async-error-handling"
    }
  ]
}
