use std::fmt;
#[derive(Debug)]
pub enum CacheError {
Backend {
source: redis::RedisError,
},
Decode {
source: serde_json::Error,
},
PayloadTooLarge {
size: usize,
limit: usize,
},
ZeroTtl,
}
impl CacheError {
pub(crate) fn backend(source: redis::RedisError) -> Self {
Self::Backend { source }
}
}
impl fmt::Display for CacheError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Backend { source } => write!(formatter, "cache backend error: {source}"),
Self::Decode { source } => write!(formatter, "cache value decode error: {source}"),
Self::PayloadTooLarge { size, limit } => {
write!(formatter, "payload size {size} exceeds limit {limit}")
}
Self::ZeroTtl => write!(formatter, "ttl must not be zero"),
}
}
}
impl std::error::Error for CacheError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Backend { source } => Some(source),
Self::Decode { source } => Some(source),
Self::PayloadTooLarge { .. } | Self::ZeroTtl => None,
}
}
}
impl From<redis::RedisError> for CacheError {
fn from(source: redis::RedisError) -> Self {
Self::Backend { source }
}
}
#[derive(Debug)]
pub enum CacheConfigError {
InvalidUrl { detail: String },
ZeroResponseTimeout,
ZeroPayloadLimit,
EmptyNamespace,
NamespaceEndsWithSeparator,
NamespaceContainsControlChar,
}
impl fmt::Display for CacheConfigError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InvalidUrl { detail } => {
write!(formatter, "invalid cache connection URL: {detail}")
}
Self::ZeroResponseTimeout => write!(formatter, "response_timeout must not be zero"),
Self::ZeroPayloadLimit => write!(formatter, "max_payload_size must not be zero"),
Self::EmptyNamespace => write!(formatter, "namespace prefix must not be empty"),
Self::NamespaceEndsWithSeparator => {
write!(
formatter,
"namespace prefix must not end with the separator ':'"
)
}
Self::NamespaceContainsControlChar => {
write!(
formatter,
"namespace prefix must not contain control characters"
)
}
}
}
}
impl std::error::Error for CacheConfigError {}
#[derive(Debug)]
pub enum CacheConnectError {
Config {
source: CacheConfigError,
},
Backend {
source: redis::RedisError,
},
}
impl CacheConnectError {
pub(crate) fn config(source: CacheConfigError) -> Self {
Self::Config { source }
}
pub(crate) fn backend(source: redis::RedisError) -> Self {
Self::Backend { source }
}
}
impl fmt::Display for CacheConnectError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Config { source } => write!(formatter, "cache configuration invalid: {source}"),
Self::Backend { source } => write!(formatter, "cache connection failed: {source}"),
}
}
}
impl std::error::Error for CacheConnectError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Config { source } => Some(source),
Self::Backend { source } => Some(source),
}
}
}
#[derive(Debug)]
pub struct CacheHealthError {
source: redis::RedisError,
}
impl CacheHealthError {
pub(crate) fn new(source: redis::RedisError) -> Self {
Self { source }
}
#[must_use]
pub fn source_error(&self) -> &redis::RedisError {
&self.source
}
}
impl fmt::Display for CacheHealthError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "cache ping failed: {}", self.source)
}
}
impl std::error::Error for CacheHealthError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(&self.source)
}
}