use std::fmt;
use crate::capability::BackendKind;
use crate::ownership::ResourceId;
pub type Result<T, E = Error> = std::result::Result<T, E>;
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
#[error("resource is gone on {backend}: {resource}: {message}")]
ResourceGone {
backend: BackendKind,
resource: ResourceId,
message: String,
},
#[error("platform error on {backend} for {resource}: {message}")]
ResourcePlatform {
backend: BackendKind,
resource: ResourceId,
message: String,
},
#[error("resource identity mismatch on {backend} for {resource}: {message}")]
ResourceIdentity {
backend: BackendKind,
resource: ResourceId,
message: String,
},
#[error("unsupported operation on {backend}: {reason}")]
Unsupported {
backend: BackendKind,
reason: String,
},
#[error("operation requires elevated privileges: {0}")]
RequiresPrivilege(String),
#[error("backend is unavailable: {0}")]
BackendUnavailable(String),
#[error("operation timed out on {resource}: {operation}")]
Timeout {
resource: ResourceId,
operation: String,
},
#[error("resource conflict on {resource}: {reason}")]
Conflict {
resource: ResourceId,
reason: ConflictReason,
},
#[error("external modification detected on {resource}: {detail}")]
ExternalModification {
resource: ResourceId,
detail: String,
},
#[error("invalid configuration: {0}")]
InvalidConfig(String),
#[error("update requires a fresh lease: owned {owned:?} vs requested {requested:?}")]
UpdateRequiresRebind {
owned: Vec<ResourceId>,
requested: Vec<ResourceId>,
},
#[error("verification failed on {resource}: {detail}")]
VerificationFailed {
resource: ResourceId,
detail: String,
},
#[error(
"unsupported journal schema version {found} in {path} (supported: {supported}); clear or reset old osdns state before upgrading"
)]
UnsupportedJournalVersion {
path: std::path::PathBuf,
found: u32,
supported: u32,
},
#[error("journal is corrupt: {0}")]
JournalCorrupt(String),
#[error(transparent)]
Io(#[from] std::io::Error),
#[error("platform error on {backend}: {message}")]
Platform {
backend: BackendKind,
message: String,
},
}
impl Error {
pub(crate) fn invalid_config(message: impl fmt::Display) -> Self {
Error::InvalidConfig(message.to_string())
}
pub(crate) fn unsupported(backend: BackendKind, reason: impl fmt::Display) -> Self {
Error::Unsupported {
backend,
reason: reason.to_string(),
}
}
pub(crate) fn platform(backend: BackendKind, message: impl fmt::Display) -> Self {
Error::Platform {
backend,
message: message.to_string(),
}
}
pub fn is_external_modification(&self) -> bool {
matches!(self, Error::ExternalModification { .. })
}
}
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
#[non_exhaustive]
pub enum ConflictReason {
#[error("the resource is already owned by an active lease in this process")]
AlreadyLeasedInProcess,
#[error("an unresolved journal record from a previous lease blocks this operation: {detail}")]
StaleJournalUnresolved {
detail: String,
},
#[error("the lease is no longer active")]
LeaseNotActive,
#[error("the resource is already occupied and is not owned by this lease: {detail}")]
ResourceOccupied {
detail: String,
},
}