use core::fmt;
use reliar_core::{Classify, FailureKind, MessageId};
use crate::error::classify_sqlstate;
#[derive(Debug)]
#[non_exhaustive]
pub enum PostgresInboxError {
UnsupportedServerVersion {
required: u32,
detected: u32,
},
NotMigrated {
schema: String,
},
SchemaNotOnSearchPath {
configured: String,
observed: String,
},
NotClaimed {
scope: String,
message_id: MessageId,
},
InvalidSettings {
message: String,
},
Database {
source: sqlx::Error,
},
}
impl fmt::Display for PostgresInboxError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::UnsupportedServerVersion { required, detected } => write!(
f,
"PostgreSQL 18 or newer is required (server_version_num >= {required}); \
detected {detected} — there is no supported way to run Reliar below the floor"
),
Self::NotMigrated { schema } => write!(
f,
"relation \"{schema}.inbox\" does not exist; call \
reliar_store_postgres::migrate(&pool, ..) before constructing the store"
),
Self::SchemaNotOnSearchPath {
configured,
observed,
} => write!(
f,
"inbox did not resolve to schema \"{configured}\" (observed search_path: \
\"{observed}\"); set search_path so \"{configured}\" comes first, e.g. \
ALTER ROLE <role> SET search_path = {configured}, public"
),
Self::NotClaimed { scope, message_id } => write!(
f,
"no claimed inbox row for scope {scope:?}, message {message_id}; complete() may \
only follow a Claimed claim() in the same transaction, and never a dead one"
),
Self::InvalidSettings { message } => {
write!(f, "invalid PostgresInboxSettings: {message}")
}
Self::Database { source } => write!(f, "database error: {source}"),
}
}
}
impl std::error::Error for PostgresInboxError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Database { source } => Some(source),
Self::UnsupportedServerVersion { .. }
| Self::NotMigrated { .. }
| Self::SchemaNotOnSearchPath { .. }
| Self::NotClaimed { .. }
| Self::InvalidSettings { .. } => None,
}
}
}
impl Classify for PostgresInboxError {
fn kind(&self) -> FailureKind {
match self {
Self::UnsupportedServerVersion { .. }
| Self::NotMigrated { .. }
| Self::SchemaNotOnSearchPath { .. }
| Self::NotClaimed { .. }
| Self::InvalidSettings { .. } => FailureKind::Permanent,
Self::Database { source } => classify_sqlstate(source),
}
}
}
impl From<sqlx::Error> for PostgresInboxError {
fn from(source: sqlx::Error) -> Self {
Self::Database { source }
}
}