#[derive(Debug, thiserror::Error)]
pub enum SessionError {
#[error("Render error: {source}")]
RenderError {
#[source]
source: Box<dyn std::error::Error + Send + Sync>,
},
#[error("Input error: {source}")]
InputError {
#[source]
source: Box<dyn std::error::Error + Send + Sync>,
},
#[error("State error: {source}")]
StateError {
#[source]
source: Box<dyn std::error::Error + Send + Sync>,
},
#[error("UI error: {source}")]
UIError {
#[source]
source: Box<dyn std::error::Error + Send + Sync>,
},
#[error("Message error: {source}")]
MessageError {
#[source]
source: Box<dyn std::error::Error + Send + Sync>,
},
#[error("Cache error: {source}")]
CacheError {
#[source]
source: Box<dyn std::error::Error + Send + Sync>,
},
#[error("Resource exhausted: {resource}")]
ResourceExhausted { resource: String },
#[error("Configuration error: {source}")]
ConfigError {
#[source]
source: Box<dyn std::error::Error + Send + Sync>,
},
}
impl SessionError {
pub fn render<E: std::error::Error + Send + Sync + 'static>(error: E) -> Self {
SessionError::RenderError { source: Box::new(error) }
}
pub fn input<E: std::error::Error + Send + Sync + 'static>(error: E) -> Self {
SessionError::InputError { source: Box::new(error) }
}
pub fn state<E: std::error::Error + Send + Sync + 'static>(error: E) -> Self {
SessionError::StateError { source: Box::new(error) }
}
pub fn ui<E: std::error::Error + Send + Sync + 'static>(error: E) -> Self {
SessionError::UIError { source: Box::new(error) }
}
pub fn message<E: std::error::Error + Send + Sync + 'static>(error: E) -> Self {
SessionError::MessageError { source: Box::new(error) }
}
pub fn cache<E: std::error::Error + Send + Sync + 'static>(error: E) -> Self {
SessionError::CacheError { source: Box::new(error) }
}
pub fn config<E: std::error::Error + Send + Sync + 'static>(error: E) -> Self {
SessionError::ConfigError { source: Box::new(error) }
}
pub fn resource_exhausted(resource: impl Into<String>) -> Self {
SessionError::ResourceExhausted { resource: resource.into() }
}
}
pub type SessionResult<T> = Result<T, SessionError>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_construction() {
let err = SessionError::render("Test render error");
assert!(format!("{}", err).contains("Render error"));
}
#[test]
fn test_error_with_source() {
let io_err = std::io::Error::new(std::io::ErrorKind::Other, "IO error");
let session_err = SessionError::input(io_err);
assert!(format!("{}", session_err).contains("Input error"));
}
#[test]
fn test_error_variants() {
let render_err = SessionError::render("Render failed");
let input_err = SessionError::input("Input failed");
let state_err = SessionError::state("State failed");
let ui_err = SessionError::ui("UI failed");
let message_err = SessionError::message("Message failed");
let cache_err = SessionError::cache("Cache failed");
let resource_err = SessionError::resource_exhausted("memory");
let config_err = SessionError::config("Config failed");
assert!(format!("{}", render_err).contains("Render error"));
assert!(format!("{}", input_err).contains("Input error"));
assert!(format!("{}", state_err).contains("State error"));
assert!(format!("{}", ui_err).contains("UI error"));
assert!(format!("{}", message_err).contains("Message error"));
assert!(format!("{}", cache_err).contains("Cache error"));
assert!(format!("{}", resource_err).contains("Resource exhausted"));
assert!(format!("{}", config_err).contains("Configuration error"));
}
#[test]
fn test_error_sources() {
let io_err = std::io::Error::new(std::io::ErrorKind::Other, "IO error");
let session_err = SessionError::input(io_err);
if let Some(source) = session_err.source() {
assert_eq!(format!("{}", source), "IO error");
} else {
panic!("Expected source error");
}
}
#[test]
fn test_result_type() {
let result: SessionResult<()> = Err(SessionError::render("Test"));
assert!(result.is_err());
let result: SessionResult<()> = Ok(());
assert!(result.is_ok());
}
}