use super::Severity;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum DnsError {
#[error("Payload rejected: JSON nested too deeply")]
NestedTooDeeply,
#[error("Failed to parse DNS zone: {0}")]
ParseError(#[from] serde_json::Error),
#[error("Maximum of 50 DNS records allowed per zone to prevent network bloat")]
TooManyRecords,
#[error("Invalid label length: {0}")]
InvalidLabelLength(String),
#[error("Invalid label character: {0}")]
InvalidLabelCharacters(String),
#[error("CNAME record for '{0}' must be the only record")]
InvalidCnameConfiguration(String),
#[error("TXT record too long for label {0}")]
TxtRecordTooLong(String),
#[error("CNAME target length invalid for label {0}")]
InvalidCnameTarget(String),
#[error("Invalid PeerId string: {0}")]
InvalidPeerId(String),
#[error("Invalid KID string (missing prefix): {0}")]
InvalidKid(String),
#[error("Invalid IPFS CID string: {0}")]
InvalidIpfsCid(String),
}
impl PartialEq for DnsError {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::NestedTooDeeply, Self::NestedTooDeeply) => true,
(Self::ParseError(a), Self::ParseError(b)) => a.to_string() == b.to_string(),
(Self::TooManyRecords, Self::TooManyRecords) => true,
(Self::InvalidLabelLength(a), Self::InvalidLabelLength(b)) => a == b,
(Self::InvalidLabelCharacters(a), Self::InvalidLabelCharacters(b)) => a == b,
(Self::InvalidCnameConfiguration(a), Self::InvalidCnameConfiguration(b)) => a == b,
(Self::TxtRecordTooLong(a), Self::TxtRecordTooLong(b)) => a == b,
(Self::InvalidCnameTarget(a), Self::InvalidCnameTarget(b)) => a == b,
(Self::InvalidPeerId(a), Self::InvalidPeerId(b)) => a == b,
(Self::InvalidKid(a), Self::InvalidKid(b)) => a == b,
(Self::InvalidIpfsCid(a), Self::InvalidIpfsCid(b)) => a == b,
_ => false,
}
}
}
impl Eq for DnsError {}
impl DnsError {
pub fn code(&self) -> &'static str {
match self {
Self::NestedTooDeeply => "KIN-DNS-001",
Self::ParseError(_) => "KIN-DNS-002",
Self::TooManyRecords => "KIN-DNS-003",
Self::InvalidLabelLength(_) => "KIN-DNS-004",
Self::InvalidLabelCharacters(_) => "KIN-DNS-005",
Self::InvalidCnameConfiguration(_) => "KIN-DNS-006",
Self::TxtRecordTooLong(_) => "KIN-DNS-007",
Self::InvalidCnameTarget(_) => "KIN-DNS-008",
Self::InvalidPeerId(_) => "KIN-DNS-009",
Self::InvalidKid(_) => "KIN-DNS-010",
Self::InvalidIpfsCid(_) => "KIN-DNS-011",
}
}
pub fn error_type_uri(&self) -> String {
format!("{}/errors/{}", crate::constants::DOCS_URL, self.code())
}
pub fn severity(&self) -> Severity {
Severity::Warning
}
pub fn is_retryable(&self) -> bool {
false }
pub fn user_message(&self) -> String {
match self {
Self::NestedTooDeeply => {
"The DNS zone contains data that is nested too deeply.".to_string()
}
Self::ParseError(_) => "Failed to parse the DNS zone data.".to_string(),
Self::TooManyRecords => {
"The DNS zone contains too many records (maximum 50).".to_string()
}
Self::InvalidLabelLength(_) => "A DNS record label has an invalid length.".to_string(),
Self::InvalidLabelCharacters(_) => {
"A DNS record label contains invalid characters.".to_string()
}
Self::InvalidCnameConfiguration(_) => {
"A CNAME record must be the only record for its label.".to_string()
}
Self::TxtRecordTooLong(_) => {
"A TXT record is too long (maximum 255 bytes).".to_string()
}
Self::InvalidCnameTarget(_) => "A CNAME target is invalid or too long.".to_string(),
Self::InvalidPeerId(_) => "A PeerId string is invalid.".to_string(),
Self::InvalidKid(_) => {
"A KID string is invalid or missing the 'did:kin:' prefix.".to_string()
}
Self::InvalidIpfsCid(_) => "An IPFS CID string is invalid.".to_string(),
}
}
}