use thiserror::Error;
#[non_exhaustive]
#[derive(Debug, Error, Clone)]
pub enum Error {
#[error("invalid URL: {0}")]
UrlParse(#[from] url::ParseError),
#[error("invalid URL for backend: {0}")]
InvalidUrl(String),
#[error("unsupported scheme: {0}")]
UnknownScheme(String),
#[error("{scheme} does not support {operation}")]
UnsupportedOperation {
scheme: &'static str,
operation: &'static str,
},
#[error("not found: {0}")]
NotFound(String),
#[error("permission denied: {0}")]
PermissionDenied(String),
#[error("authentication failed: {0}")]
AuthenticationFailed(String),
#[error("precondition failed: {0}")]
PreconditionFailed(String),
#[error("backend '{scheme}' failed: {message}")]
Backend {
scheme: &'static str,
kind: BackendFailureKind,
message: String,
},
}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BackendFailureKind {
Transient,
Throttled,
Permanent,
}
impl Error {
pub fn is_transient(&self) -> bool {
matches!(
self,
Error::Backend {
kind: BackendFailureKind::Transient | BackendFailureKind::Throttled,
..
}
)
}
#[allow(unreachable_patterns)]
pub fn kind(&self) -> &'static str {
match self {
Error::UrlParse(_) => "url_parse",
Error::InvalidUrl(_) => "invalid_url",
Error::UnknownScheme(_) => "unknown_scheme",
Error::UnsupportedOperation { .. } => "unsupported_operation",
Error::NotFound(_) => "not_found",
Error::PermissionDenied(_) => "permission_denied",
Error::AuthenticationFailed(_) => "auth_failed",
Error::PreconditionFailed(_) => "precondition_failed",
Error::Backend { .. } => "backend",
_ => "other",
}
}
}