Skip to content

Commit

Permalink
Extract error sorting code to module. (#1077)
Browse files Browse the repository at this point in the history
* Extract error sorting code to module.

This will allow FFI clients to use the same logic.

* ++redis-rs

* fix comments.
  • Loading branch information
nihohit authored Mar 6, 2024
1 parent b6892bc commit ffb34fc
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 43 deletions.
27 changes: 11 additions & 16 deletions glide-core/src/client/value_conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub(crate) fn convert_to_expected_type(
match inner_value {
Value::BulkString(_) => Ok((
key_str,
Value::Double(from_owned_redis_value::<f64>(inner_value)?.into()),
Value::Double(from_owned_redis_value::<f64>(inner_value)?),
)),
Value::Double(_) => Ok((key_str, inner_value)),
_ => Err((
Expand Down Expand Up @@ -89,13 +89,11 @@ pub(crate) fn convert_to_expected_type(
)
.into()),
},
ExpectedReturnType::Double => {
Ok(Value::Double(from_owned_redis_value::<f64>(value)?.into()))
}
ExpectedReturnType::Double => Ok(Value::Double(from_owned_redis_value::<f64>(value)?)),
ExpectedReturnType::Boolean => Ok(Value::Boolean(from_owned_redis_value::<bool>(value)?)),
ExpectedReturnType::DoubleOrNull => match value {
Value::Nil => Ok(value),
_ => Ok(Value::Double(from_owned_redis_value::<f64>(value)?.into())),
_ => Ok(Value::Double(from_owned_redis_value::<f64>(value)?)),
},
ExpectedReturnType::ZrankReturnType => match value {
Value::Nil => Ok(value),
Expand Down Expand Up @@ -306,10 +304,7 @@ mod tests {
Value::BulkString(b"key2".to_vec()),
Value::BulkString(b"20.8".to_vec()),
),
(
Value::Double(20.5.into()),
Value::BulkString(b"30.2".to_vec()),
),
(Value::Double(20.5), Value::BulkString(b"30.2".to_vec())),
];

let converted_map = convert_to_expected_type(
Expand All @@ -328,15 +323,15 @@ mod tests {

let (key, value) = &converted_map[0];
assert_eq!(*key, Value::BulkString(b"key1".to_vec()));
assert_eq!(*value, Value::Double(10.5.into()));
assert_eq!(*value, Value::Double(10.5));

let (key, value) = &converted_map[1];
assert_eq!(*key, Value::BulkString(b"key2".to_vec()));
assert_eq!(*value, Value::Double(20.8.into()));
assert_eq!(*value, Value::Double(20.8));

let (key, value) = &converted_map[2];
assert_eq!(*key, Value::BulkString(b"20.5".to_vec()));
assert_eq!(*value, Value::Double(30.2.into()));
assert_eq!(*value, Value::Double(30.2));

let array_of_arrays = vec![
Value::Array(vec![
Expand All @@ -345,7 +340,7 @@ mod tests {
]),
Value::Array(vec![
Value::BulkString(b"key2".to_vec()),
Value::Double(20.5.into()),
Value::Double(20.5),
]),
];

Expand All @@ -365,11 +360,11 @@ mod tests {

let (key, value) = &converted_map[0];
assert_eq!(*key, Value::BulkString(b"key1".to_vec()));
assert_eq!(*value, Value::Double(10.5.into()));
assert_eq!(*value, Value::Double(10.5));

let (key, value) = &converted_map[1];
assert_eq!(*key, Value::BulkString(b"key2".to_vec()));
assert_eq!(*value, Value::Double(20.5.into()));
assert_eq!(*value, Value::Double(20.5));

let array_of_arrays_err: Vec<Value> = vec![Value::Array(vec![
Value::BulkString(b"key".to_vec()),
Expand Down Expand Up @@ -410,7 +405,7 @@ mod tests {
assert_eq!(array_result.len(), 2);

assert_eq!(array_result[0], Value::BulkString(b"key".to_vec()));
assert_eq!(array_result[1], Value::Double(20.5.into()));
assert_eq!(array_result[1], Value::Double(20.5));

let array_err = vec![Value::BulkString(b"key".to_vec())];
assert!(convert_to_expected_type(
Expand Down
34 changes: 34 additions & 0 deletions glide-core/src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0
*/

use redis::RedisError;

#[repr(C)]
pub enum RequestErrorType {
Unspecified = 0,
ExecAbort = 1,
Timeout = 2,
Disconnect = 3,
}

pub fn error_type(error: &RedisError) -> RequestErrorType {
if error.is_timeout() {
RequestErrorType::Timeout
} else if error.is_unrecoverable_error() {
RequestErrorType::Disconnect
} else if matches!(error.kind(), redis::ErrorKind::ExecAbortError) {
RequestErrorType::ExecAbort
} else {
RequestErrorType::Unspecified
}
}

pub fn error_message(error: &RedisError) -> String {
let error_message = error.to_string();
if matches!(error_type(error), RequestErrorType::Disconnect) {
format!("Received connection error `{error_message}`. Will attempt to reconnect")
} else {
error_message
}
}
1 change: 1 addition & 0 deletions glide-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ mod retry_strategies;
pub mod rotating_buffer;
mod socket_listener;
pub use socket_listener::*;
pub mod errors;
pub mod scripts_container;
33 changes: 13 additions & 20 deletions glide-core/src/socket_listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use super::rotating_buffer::RotatingBuffer;
use crate::client::Client;
use crate::connection_request::ConnectionRequest;
use crate::errors::{error_message, error_type, RequestErrorType};
use crate::redis_request::{
command, redis_request, Command, RedisRequest, RequestType, Routes, ScriptInvocation,
SlotTypes, Transaction,
Expand Down Expand Up @@ -217,28 +218,20 @@ async fn write_result(
Some(response::response::Value::RequestError(request_error))
}
Err(ClienUsageError::Redis(err)) => {
let error_message = err.to_string();
let error_message = error_message(&err);
log_warn("received error", error_message.as_str());
log_debug("received error", format!("for callback {}", callback_index));
let mut request_error = response::RequestError::default();
if err.is_connection_dropped() {
request_error.type_ = response::RequestErrorType::Disconnect.into();
request_error.message = format!(
"Received connection error `{error_message}`. Will attempt to reconnect"
)
.into();
} else if err.is_timeout() {
request_error.type_ = response::RequestErrorType::Timeout.into();
request_error.message = error_message.into();
} else {
request_error.type_ = match err.kind() {
redis::ErrorKind::ExecAbortError => {
response::RequestErrorType::ExecAbort.into()
}
_ => response::RequestErrorType::Unspecified.into(),
};
request_error.message = error_message.into();
}
let request_error = response::RequestError {
type_: match error_type(&err) {
RequestErrorType::Unspecified => response::RequestErrorType::Unspecified,
RequestErrorType::ExecAbort => response::RequestErrorType::ExecAbort,
RequestErrorType::Timeout => response::RequestErrorType::Timeout,
RequestErrorType::Disconnect => response::RequestErrorType::Disconnect,
}
.into(),
message: error_message.into(),
..Default::default()
};
Some(response::response::Value::RequestError(request_error))
}
};
Expand Down
2 changes: 1 addition & 1 deletion glide-core/tests/test_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ pub(crate) mod shared_client_tests {
Value::Boolean(true),
Value::Int(1),
Value::Okay,
Value::Double(0.5.into()),
Value::Double(0.5),
Value::Int(1),
]),)
);
Expand Down
2 changes: 1 addition & 1 deletion java/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ fn redis_value_to_java<'local>(env: &mut JNIEnv<'local>, val: Value) -> JObject<
hashmap
}
Value::Double(float) => env
.new_object("java/lang/Double", "(D)V", &[float.into_inner().into()])
.new_object("java/lang/Double", "(D)V", &[float.into()])
.unwrap(),
Value::Boolean(bool) => env
.new_object("java/lang/Boolean", "(Z)V", &[bool.into()])
Expand Down
4 changes: 1 addition & 3 deletions node/rust-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,7 @@ fn redis_value_to_js(val: Value, js_env: Env) -> Result<JsUnknown> {
}
Ok(obj.into_unknown())
}
Value::Double(float) => js_env
.create_double(float.into())
.map(|val| val.into_unknown()),
Value::Double(float) => js_env.create_double(float).map(|val| val.into_unknown()),
Value::Boolean(bool) => js_env.get_boolean(bool).map(|val| val.into_unknown()),
// format is ignored, as per the RESP3 recommendations -
// "Normal client libraries may ignore completely the difference between this"
Expand Down
2 changes: 1 addition & 1 deletion python/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ fn glide(_py: Python, m: &PyModule) -> PyResult<()> {
let set = PySet::new(py, set.iter())?;
Ok(set.into_py(py))
}
Value::Double(double) => Ok(PyFloat::new(py, double.into()).into_py(py)),
Value::Double(double) => Ok(PyFloat::new(py, double).into_py(py)),
Value::Boolean(boolean) => Ok(PyBool::new(py, boolean).into_py(py)),
Value::VerbatimString { format: _, text } => Ok(text.into_py(py)),
Value::BigNumber(bigint) => Ok(bigint.into_py(py)),
Expand Down
2 changes: 1 addition & 1 deletion submodules/redis-rs

0 comments on commit ffb34fc

Please sign in to comment.