Тип ответа не совместим со строкой.» (ответ был нулевым) при повторном запросе

#rust

Вопрос:

Я использую этот код для выполнения запроса redis в rust, мой минимальный пример воспроизведения содержит 3 файла. это моя main.rs функция:

 #[tokio::main] async fn main() {  const REDIS_CON_STRING: amp;str = "redis://default:password@cruise-redis-headless.reddwarf-cache.svc.cluster.local:6379/3";  let redis_client = redis::Client::open(REDIS_CON_STRING).expect("can create redis client");  let mut redis_conn = get_con(redis_client);  let cached_playlist = get_str(amp;mut redis_conn.unwrap(), "dd").await;  if cached_playlist.as_ref().unwrap().is_empty() {  print!("d")  } }  

и это redis_util.rs для определения операции redis:

 use redis::{Commands, Connection, FromRedisValue}; use crate::mobc_error::DirectError::{RedisClientError, RedisCMDError, RedisTypeError}; use crate::mobc_error::Error;  type Resultlt;Tgt; = std::result::Resultlt;T, Errorgt;;  pub fn get_con(client: redis::Client) -gt; Resultlt;Connectiongt; {  client  .get_connection()  .map_err(|e| RedisClientError(e).into()) }  pub async fn set_str(  con: amp;mut Connection,  key: amp;str,  value: amp;str,  ttl_seconds: usize, ) -gt; Resultlt;()gt; {  con.set(key, value).map_err(RedisCMDError)?;  if ttl_seconds gt; 0 {  con.expire(key, ttl_seconds).map_err(RedisCMDError)?;  }  Ok(()) }  pub async fn get_str(con: amp;mut Connection, key: amp;str) -gt; Resultlt;Stringgt; {  let value = con.get(key).map_err(RedisCMDError)?;  FromRedisValue::from_redis_value(amp;value).map_err(|e| RedisTypeError(e).into()) }  

и в этом заключается ошибка определения mobc_error.rs :

 use thiserror::Error;  #[derive(Error, Debug)] pub enum Error {  #[error("mobc error: {0}")]  MobcError(#[from] MobcError),  #[error("direct redis error: {0}")]  DirectError(#[from] DirectError),  }  #[derive(Error, Debug)] pub enum MobcError {  #[error("could not get redis connection from pool : {0}")]  RedisPoolError(mobc::Errorlt;mobc_redis::redis::RedisErrorgt;),  #[error("error parsing string from redis result: {0}")]  RedisTypeError(redis::RedisError),  #[error("error executing redis command: {0}")]  RedisCMDError(redis::RedisError),  #[error("error creating Redis client: {0}")]  RedisClientError(redis::RedisError), }  #[derive(Error, Debug)] pub enum DirectError {  #[error("error parsing string from redis result: {0}")]  RedisTypeError(redis::RedisError),  #[error("error executing redis command: {0}")]  RedisCMDError(redis::RedisError),  #[error("error creating Redis client: {0}")]  RedisClientError(redis::RedisError), }  

some of the dependencies I am using in cargo.toml:

 thiserror = "1.0" mobc = "0.7" mobc-redis = "0.7.0" redis = "0.21.3" tokio = { version = "1.12.0", features = ["full"] }  

when I get the result and check the result in this line cached_playlist.as_ref().unwrap().is_empty() , shows error like this:

 /Users/dolphin/Documents/GitHub/rust-learn/target/debug/rust-learn thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: DirectError(RedisTypeError(Response was of incompatible type: "Response type not string compatible." (response was nil)))', src/main.rs:31:33 stack backtrace:  0: rust_begin_unwind  at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/std/src/panicking.rs:515:5  1: core::panicking::panic_fmt  at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/panicking.rs:92:14  2: core::result::unwrap_failed  at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/result.rs:1355:5  3: core::result::Resultlt;T,Egt;::unwrap  at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/result.rs:1037:23  4: rust_learn::main::{{closure}}  at ./src/main.rs:31:8  5: lt;core::future::from_generator::GenFuturelt;Tgt; as core::future::future::Futuregt;::poll  at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/future/mod.rs:80:19  6: tokio::park::thread::CachedParkThread::block_on::{{closure}}  at /Users/dolphin/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.12.0/src/park/thread.rs:263:54  7: tokio::coop::with_budget::{{closure}}  at /Users/dolphin/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.12.0/src/coop.rs:106:9  8: std::thread::local::LocalKeylt;Tgt;::try_with  at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/std/src/thread/local.rs:400:16  9: std::thread::local::LocalKeylt;Tgt;::with  at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/std/src/thread/local.rs:376:9  10: tokio::coop::with_budget  at /Users/dolphin/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.12.0/src/coop.rs:99:5  11: tokio::coop::budget  at /Users/dolphin/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.12.0/src/coop.rs:76:5  12: tokio::park::thread::CachedParkThread::block_on  at /Users/dolphin/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.12.0/src/park/thread.rs:263:31  13: tokio::runtime::enter::Enter::block_on  at /Users/dolphin/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.12.0/src/runtime/enter.rs:151:13  14: tokio::runtime::thread_pool::ThreadPool::block_on  at /Users/dolphin/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.12.0/src/runtime/thread_pool/mod.rs:77:9  15: tokio::runtime::Runtime::block_on  at /Users/dolphin/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.12.0/src/runtime/mod.rs:463:43  16: rust_learn::main  at ./src/main.rs:34:5  17: core::ops::function::FnOnce::call_once  at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/ops/function.rs:227:5 note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.  

что мне делать, когда он вернется равным нулю? как проверить нулевое значение? Я не нашел нулевого определения в ржавчине. Я пробовал вот так:

 if redis::Value::Nil == cached_playlist.as_ref().unwrap() {  print!("d")  }  

но показывает ошибку:

 error[E0308]: mismatched types  --gt; src/main.rs:32:29  | 32 | if redis::Value::Nil == cached_playlist.as_ref().unwrap() {  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `redis::Value`, found `amp;std::string::String`  

Комментарии:

1. Я добавляю свой минимальный пример воспроизведения, просто замените URL-адрес redis, чтобы воспроизвести эту проблему. @kmdreko

2. Вам нужно проверить наличие nil в вашей get_str функции, прежде чем пытаться преобразовать значение в a String .

3. Мне интересно, можно ли определить объект, совместимый со всеми типами данных, такими как Java? @Jmb

4. Я не знал, как проверить, содержит результат ноль или нет. @Jmb

5. Если вам нужно значение, совместимое со «всеми» типами, вы можете использовать redis::Value напрямую (оно было создано для этого).