b7cd2b1
use std::error::Error;
use std::fmt::{self, Display, Formatter};
use kvcache::CacheError;
use kvcache::redis::RedisError;
#[derive(Debug)]
pub enum SessionError {
Serialize {
key: String,
source: serde_json::Error,
},
Deserialize {
key: String,
source: serde_json::Error,
},
Purged,
UpdateConflict {
key: String,
},
Config(String),
Store(CacheError),
Backend(RedisError),
}
impl SessionError {
pub fn config(message: impl Into<String>) -> Self {
Self::Config(message.into())
}
pub fn serialize(key: impl Into<String>, source: serde_json::Error) -> Self {
Self::Serialize {
key: key.into(),
source,
}
}
pub fn deserialize(key: impl Into<String>, source: serde_json::Error) -> Self {
Self::Deserialize {
key: key.into(),
source,
}
}
pub fn conflict(key: impl Into<String>) -> Self {
Self::UpdateConflict { key: key.into() }
}
pub fn is_purged(&self) -> bool {
matches!(self, Self::Purged)
}
pub fn is_retryable(&self) -> bool {
matches!(self, Self::Store(source) if source.is_retryable())
}
}
impl Display for SessionError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
Self::Serialize { key, source } => {
write!(f, "failed to serialize session field `{key}`: {source}")
}
Self::Deserialize { key, source } => {
write!(f, "failed to deserialize session field `{key}`: {source}")
}
Self::Purged => f.write_str("session record has been purged"),
Self::UpdateConflict { key } => {
write!(
f,
"session field `{key}` changed before its update was committed"
)
}
Self::Config(message) => write!(f, "invalid session configuration: {message}"),
Self::Store(source) => write!(f, "session store error: {source}"),
Self::Backend(source) => write!(f, "session backend error: {source}"),
}
}
}
impl Error for SessionError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::Serialize { source, .. } | Self::Deserialize { source, .. } => Some(source),
Self::Store(source) => Some(source),
Self::Backend(source) => Some(source),
Self::Purged | Self::UpdateConflict { .. } | Self::Config(_) => None,
}
}
}
impl From<CacheError> for SessionError {
fn from(value: CacheError) -> Self {
Self::Store(value)
}
}
impl From<RedisError> for SessionError {
fn from(value: RedisError) -> Self {
Self::Backend(value)
}
}