diff --git a/src/frame.rs b/src/frame.rs index ad2fa4e..3cdebdf 100644 --- a/src/frame.rs +++ b/src/frame.rs @@ -149,6 +149,7 @@ impl Frame { Frame::Error(s) => { let mut bytes = Vec::with_capacity(1 + s.len() + CRLF.len()); bytes.push(u8::from(DataType::SimpleError)); + bytes.extend_from_slice("ERR ".as_bytes()); bytes.extend_from_slice(s.as_bytes()); bytes.extend_from_slice(CRLF); bytes @@ -219,7 +220,7 @@ impl fmt::Display for Frame { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Frame::Simple(s) => write!(f, "+{}", s), - Frame::Error(s) => write!(f, "-{}", s), + Frame::Error(s) => write!(f, "-ERR {}", s), Frame::Integer(i) => write!(f, ":{}", i), Frame::Bulk(bytes) => write!(f, "${}", String::from_utf8_lossy(bytes)), Frame::Null => write!(f, "$-1"), @@ -360,14 +361,14 @@ mod tests { #[test] fn parse_simple_error_frame() { - let data = b"-Error message\r\n"; + let data = b"-ERR Error message\r\n"; let mut cursor = Cursor::new(&data[..]); let frame = Frame::parse(&mut cursor); assert!(matches!( frame, - Ok(Frame::Error(ref s)) if s == "Error message" + Ok(Frame::Error(ref s)) if s == "ERR Error message" )); } diff --git a/tests/integration.rs b/tests/integration.rs index eb6bdaa..4f6c7d4 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -85,7 +85,20 @@ async fn test_compare_err(f: impl FnOnce(&mut redis::Pipeline)) { their_response.is_err(), "Not Err, use `test_compare` instead if expecting a value" ); - assert_eq!(our_response, their_response); + + // The `redis` crate does some parsing and wrapping of the error message. See: + // https://github.com/redis-rs/redis-rs/blob/e6a59325ca963c09675fafac15fbf10ddf5f4cd4/redis/src/types.rs#L743-L766 + // + // We only care about the error message sent by the Redis server, which is the `detail`. + match (our_response, their_response) { + (Err(ref our_err), Err(ref their_err)) => { + let our_msg = our_err.detail(); + let their_msg = their_err.detail(); + + assert_eq!(our_msg, their_msg); + } + _ => {} + } } #[tokio::test]