use thiserror::Error;
#[derive(Debug, Error)]
pub enum Error {
#[error(transparent)]
AccessControl(#[from] crate::access_control::Error),
#[error(transparent)]
EventStore(#[from] crate::event_store::Error),
#[error(transparent)]
Projections(#[from] crate::projections::Error),
#[error(transparent)]
Bootstrap(#[from] crate::bootstrap::Error),
#[error(transparent)]
Encryption(#[from] crate::encryption::Error),
#[error("command rejected: {reason}")]
CommandRejected { reason: String, kind: String },
#[error("this CommandType has no decide() registered in the running process")]
NoDeciderRegistered,
#[error("database error: {0}")]
Database(#[from] sqlx::Error),
#[error("migration error: {0}")]
Migration(#[from] sqlx::migrate::MigrateError),
}
pub trait SkiljRejection {
fn code(&self) -> &str;
fn message(&self) -> String;
}
impl SkiljRejection for Error {
fn code(&self) -> &str {
match self {
Error::AccessControl(e) => e.code(),
Error::EventStore(e) => e.code(),
Error::Projections(e) => e.code(),
Error::Bootstrap(e) => e.code(),
Error::Encryption(e) => e.code(),
Error::CommandRejected { kind, .. } => kind,
Error::NoDeciderRegistered => "no_decider_registered",
Error::Database(_) => "database_error",
Error::Migration(_) => "migration_error",
}
}
fn message(&self) -> String {
match self {
Error::AccessControl(e) => e.message(),
Error::EventStore(e) => e.message(),
Error::Projections(e) => e.message(),
Error::Bootstrap(e) => e.message(),
Error::Encryption(e) => e.message(),
Error::CommandRejected { reason, .. } => reason.clone(),
Error::NoDeciderRegistered => self.to_string(),
Error::Database(e) => e.to_string(),
Error::Migration(e) => e.to_string(),
}
}
}
pub type Result<T> = std::result::Result<T, Error>;