use super::Severity;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum DrandError {
#[error("All Drand endpoints failed")]
AllEndpointsFailed,
#[error("Network error: {0}")]
Network(String),
#[error("HTTP status error: {0}")]
HttpError(u16),
#[error("No cached kyn found")]
NoCachedKyn,
#[error("Serialization error: {0}")]
Serde(#[from] serde_json::Error),
#[error("Storage error: {0}")]
Storage(#[from] crate::error::StorageError),
#[error("Reqwest error: {0}")]
Reqwest(#[from] reqwest::Error),
#[error("Invalid Drand signature")]
InvalidSignature,
#[error("Stale kyn: expected kyn ~{expected}, but got {got}")]
StaleKyn {
expected: u64,
got: u64,
},
}
impl PartialEq for DrandError {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::AllEndpointsFailed, Self::AllEndpointsFailed) => true,
(Self::Network(a), Self::Network(b)) => a == b,
(Self::HttpError(a), Self::HttpError(b)) => a == b,
(Self::NoCachedKyn, Self::NoCachedKyn) => true,
(Self::Serde(a), Self::Serde(b)) => a.to_string() == b.to_string(),
(Self::Storage(a), Self::Storage(b)) => a == b,
(Self::Reqwest(a), Self::Reqwest(b)) => a.to_string() == b.to_string(),
(Self::InvalidSignature, Self::InvalidSignature) => true,
(
Self::StaleKyn {
expected: e1,
got: g1,
},
Self::StaleKyn {
expected: e2,
got: g2,
},
) => e1 == e2 && g1 == g2,
_ => false,
}
}
}
impl Eq for DrandError {}
impl DrandError {
pub fn code(&self) -> &'static str {
match self {
Self::AllEndpointsFailed => "KIN-DRA-001",
Self::Network(_) => "KIN-DRA-002",
Self::HttpError(_) => "KIN-DRA-003",
Self::NoCachedKyn => "KIN-DRA-004",
Self::Serde(_) => "KIN-DRA-005",
Self::Storage(_) => "KIN-DRA-006",
Self::Reqwest(_) => "KIN-DRA-007",
Self::InvalidSignature => "KIN-DRA-008",
Self::StaleKyn { .. } => "KIN-DRA-009",
}
}
pub fn error_type_uri(&self) -> String {
format!("{}/errors/{}", crate::constants::DOCS_URL, self.code())
}
pub fn severity(&self) -> Severity {
match self {
Self::AllEndpointsFailed
| Self::Network(_)
| Self::HttpError(_)
| Self::NoCachedKyn
| Self::Reqwest(_)
| Self::StaleKyn { .. } => Severity::Warning,
Self::Serde(_) | Self::Storage(_) | Self::InvalidSignature => Severity::Error,
}
}
pub fn is_retryable(&self) -> bool {
matches!(
self,
Self::AllEndpointsFailed
| Self::Network(_)
| Self::HttpError(_)
| Self::Reqwest(_)
| Self::StaleKyn { .. }
)
}
pub fn user_message(&self) -> String {
match self {
Self::AllEndpointsFailed => "All network endpoints failed.".to_string(),
Self::Network(_) | Self::HttpError(_) | Self::Reqwest(_) => {
"A network error occurred while fetching the network kyn.".to_string()
}
Self::NoCachedKyn => "No cached network kyn found.".to_string(),
Self::Serde(_) => "Failed to parse the network kyn.".to_string(),
Self::Storage(_) => {
"A storage error occurred while reading or writing the kyn cache.".to_string()
}
Self::InvalidSignature => "Invalid network signature.".to_string(),
Self::StaleKyn { .. } => "The fetched network kyn was too old.".to_string(),
}
}
}