use std::{error::Error, fmt::{self}};
pub(crate)
fn map_read_err(e: std::io::Error) -> CDnsError
{
return CDnsError::new(CDnsErrorType::IoError, format!("{}", e));
}
#[derive(Debug)]
pub struct ResolverStdErr;
impl ErrorReport for ResolverStdErr
{
fn report(&self, error: crate::CDnsError)
{
eprintln!("ERROR: {}", error);
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CDnsIOError(CDnsError);
impl Error for CDnsIOError
{
fn source(&self) -> Option<&(dyn Error + 'static)>
{
Some(&self.0)
}
}
impl fmt::Display for CDnsIOError
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "{}", self.source().unwrap())
}
}
impl From<CDnsError> for CDnsIOError
{
fn from(value: CDnsError) -> Self
{
return Self(value);
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CDnsError
{
pub err_code: CDnsErrorType,
pub message: String,
}
impl CDnsError
{
pub fn new(err_code: CDnsErrorType, msg: String) -> Self
{
return CDnsError{err_code: err_code, message: msg};
}
}
impl Error for CDnsError {}
impl fmt::Display for CDnsError
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
{
write!(f, "cdns: [{}], {}", self.err_code, self.message)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CDnsErrorDnsResponse
{
DnsUnknownReqID,
DnsInvalidStatusBits,
DnsResponseFromUnknownDestination,
DnsBadFormat,
DnsIncorrectRdlen,
DnsProtocolViolation,
DnsUnknownRecordType,
DnsUnknownQclassType,
DnsRequestAnswerMismatch,
DnsRecordAssertion,
DnsPunycodeError,
DnsHttpsParse,
}
impl fmt::Display for CDnsErrorDnsResponse
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
{
match *self
{
Self::DnsUnknownReqID =>
write!(f, "Unknown Request ID"),
Self::DnsInvalidStatusBits =>
write!(f, "invalid bits in status field"),
Self::DnsResponseFromUnknownDestination =>
write!(f, "received a response from host which is not req origin"),
Self::DnsBadFormat =>
write!(f, "bad packet formatting"),
Self::DnsIncorrectRdlen =>
write!(f, "incorrect rdlen value"),
Self::DnsProtocolViolation =>
write!(f, "sever protocol violation"),
Self::DnsUnknownRecordType =>
write!(f, "unknown request recoed type"),
Self::DnsUnknownQclassType =>
write!(f, "unknwon qclass type"),
Self::DnsRequestAnswerMismatch =>
write!(f, "requst and anser are different"),
Self::DnsRecordAssertion =>
write!(f, "record parsing error"),
Self::DnsPunycodeError =>
write!(f, "punycode error"),
Self::DnsHttpsParse =>
write!(f, "http parsing error"),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CDnsErrorType
{
DnsResponse(CDnsErrorDnsResponse),
RespIdMismatch,
InternalError,
SoftAssertion,
IoError,
MessageTruncated,
RequestTimeout,
ConfigError,
DnsNotAvailable,
HttpError,
SocketNotSupported,
PunycodeNotAscii,
}
impl fmt::Display for CDnsErrorType
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
{
match self
{
Self::DnsResponse(e) =>
write!(f, "{}", e),
Self::RespIdMismatch =>
write!(f, "Response ID mismatch"),
Self::InternalError =>
write!(f, "Internal Error"),
Self::SoftAssertion =>
write!(f, "SoftAssertionTrap"),
Self::IoError =>
write!(f, "IO Error"),
Self::MessageTruncated =>
write!(f, "Message was truncated"),
Self::RequestTimeout =>
write!(f, "Request receive timout"),
Self::ConfigError =>
write!(f, "Config file error"),
Self::DnsNotAvailable =>
write!(f, "DNS not available"),
Self::HttpError =>
write!(f, "HTTP Error"),
Self::SocketNotSupported =>
write!(f, "Socket connection is not supported"),
Self::PunycodeNotAscii =>
write!(f, "Received punycode with non ASCII characters"),
}
}
}
pub type CDnsResult<T> = Result<T, CDnsError>;
#[macro_export]
macro_rules! internal_error
{
($src:expr,$($arg:tt)*) => (
return std::result::Result::Err($crate::CDnsError::new($src, format!($($arg)*)))
)
}
#[macro_export]
macro_rules! internal_error_map
{
($src:expr,$($arg:tt)*) => (
$crate::CDnsError::new($src, format!($($arg)*))
)
}
#[cfg(feature = "no_error_output")]
#[macro_export]
macro_rules! write_error
{
($src:expr) => (
{let _ = $src;}
)
}
#[cfg(not(feature = "no_error_output"))]
#[macro_export]
macro_rules! write_error
{
($src:expr) => (
eprintln!("{}", $src)
)
}
pub trait ErrorReport: fmt::Debug
{
fn report(&self, error: CDnsError);
}