#[derive(Debug, thiserror::Error)]
pub enum ShoveError {
#[error("serialization error: {0}")]
Serialization(#[from] serde_json::Error),
#[error("connection error: {0}")]
Connection(String),
#[error("topology error: {0}")]
Topology(String),
#[error("validation error: {0}")]
Validation(String),
#[error("unknown backend error: {0}")]
Unknown(String),
}
impl ShoveError {
pub fn is_retryable(&self) -> bool {
matches!(self, ShoveError::Connection(_))
}
}
pub type Result<T> = std::result::Result<T, ShoveError>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn display_serialization_error() {
let json_err = serde_json::from_str::<String>("not json").unwrap_err();
let err = ShoveError::Serialization(json_err);
let msg = err.to_string();
assert!(msg.starts_with("serialization error:"), "got: {msg}");
}
#[test]
fn display_connection_error() {
let err = ShoveError::Connection("channel closed".into());
assert_eq!(err.to_string(), "connection error: channel closed");
}
#[test]
fn display_topology_error() {
let err = ShoveError::Topology("missing exchange".into());
assert_eq!(err.to_string(), "topology error: missing exchange");
}
#[test]
fn from_serde_json_error() {
let json_err = serde_json::from_str::<String>("{}").unwrap_err();
let err: ShoveError = json_err.into();
assert!(matches!(err, ShoveError::Serialization(_)));
}
}