use thiserror::Error;
pub type Result<T> = std::result::Result<T, ConsulError>;
#[derive(Error, Debug)]
pub enum ConsulError {
#[error("HTTP request error: {0}")]
HttpError(#[from] reqwest::Error),
#[error("URL parsing error: {0}")]
UrlError(#[from] url::ParseError),
#[error("JSON error: {0}")]
JsonError(#[from] serde_json::Error),
#[error("Consul API error: {status} - {message}")]
ApiError { status: u16, message: String },
#[error("Key not found: {0}")]
KeyNotFound(String),
#[error("Session not found: {0}")]
SessionNotFound(String),
#[error("ACL permission denied: {0}")]
PermissionDenied(String),
#[error("Invalid configuration: {0}")]
InvalidConfig(String),
#[error("TLS error: {0}")]
TlsError(String),
#[error("Request timeout")]
Timeout,
#[error("CAS operation failed")]
CasFailed,
#[error("Lock acquisition failed")]
LockFailed,
#[error("Invalid response: {0}")]
InvalidResponse(String),
#[error("Internal error: {0}")]
Internal(String),
}
impl ConsulError {
pub fn api_error(status: u16, message: impl Into<String>) -> Self {
ConsulError::ApiError {
status,
message: message.into(),
}
}
pub fn is_retryable(&self) -> bool {
matches!(
self,
ConsulError::HttpError(_) | ConsulError::Timeout
)
}
pub fn is_not_found(&self) -> bool {
matches!(
self,
ConsulError::KeyNotFound(_) | ConsulError::SessionNotFound(_)
) || matches!(self, ConsulError::ApiError { status, .. } if *status == 404)
}
}