use std::fmt;
#[derive(Debug)]
pub(crate) enum DbCommandError {
MissingDatabaseUrl,
Config(arcature_db::DbConfigError),
Connect(arcature_db::DbConnectError),
AdvisoryLock(arcature_db::sqlx::Error),
AdvisoryLockNotOwned,
Runtime(String),
DestructiveRequiresForce(&'static str),
ReadStdin(std::io::Error),
LintCritical,
}
impl fmt::Display for DbCommandError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::MissingDatabaseUrl => {
write!(formatter, "DATABASE_URL is not set")
}
Self::Config(error) => {
write!(formatter, "database configuration error: {error}")
}
Self::Connect(error) => {
write!(formatter, "database connection error: {error}")
}
Self::AdvisoryLock(error) => {
write!(formatter, "advisory lock error: {error}")
}
Self::AdvisoryLockNotOwned => {
write!(
formatter,
"migration advisory lock was not owned by its session"
)
}
Self::Runtime(detail) => {
write!(formatter, "cannot create async runtime: {detail}")
}
Self::DestructiveRequiresForce(command) => {
write!(
formatter,
"arc db {command} is destructive — pass --force to confirm"
)
}
Self::ReadStdin(error) => {
write!(formatter, "cannot read migration SQL from stdin: {error}")
}
Self::LintCritical => {
write!(
formatter,
"arc db lint found a critical migration risk — review the report above"
)
}
}
}
}
impl std::error::Error for DbCommandError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Config(error) => Some(error),
Self::Connect(error) => Some(error),
Self::AdvisoryLock(error) => Some(error),
Self::ReadStdin(error) => Some(error),
_ => None,
}
}
}
impl From<arcature_db::DbConfigError> for DbCommandError {
fn from(value: arcature_db::DbConfigError) -> Self {
Self::Config(value)
}
}
impl From<arcature_db::DbConnectError> for DbCommandError {
fn from(value: arcature_db::DbConnectError) -> Self {
Self::Connect(value)
}
}