trust_dns_client/error/
client_error.rs1use std::{fmt, io};
11
12use futures_channel::mpsc;
13use thiserror::Error;
14
15#[cfg(feature = "backtrace")]
16use crate::proto::{trace, ExtBacktrace};
17use trust_dns_proto::error::{DnsSecError, DnsSecErrorKind, ProtoError, ProtoErrorKind};
18
19pub type Result<T> = ::std::result::Result<T, Error>;
21
22#[derive(Debug, Error)]
24#[non_exhaustive]
25pub enum ErrorKind {
26 #[error("{0}")]
28 Message(&'static str),
29
30 #[error("{0}")]
32 Msg(String),
33
34 #[error("dnssec error")]
37 DnsSec(#[from] DnsSecError),
38
39 #[error("io error")]
41 Io(#[from] std::io::Error),
42
43 #[error("proto error")]
45 Proto(#[from] ProtoError),
46
47 #[error("error sending to mpsc: {0}")]
49 SendError(#[from] mpsc::SendError),
50
51 #[error("request timed out")]
53 Timeout,
54}
55
56impl Clone for ErrorKind {
57 fn clone(&self) -> Self {
58 use self::ErrorKind::*;
59 match self {
60 Message(msg) => Message(msg),
61 Msg(ref msg) => Msg(msg.clone()),
62 DnsSec(dnssec) => DnsSec(dnssec.clone()),
64 Io(io) => Io(std::io::Error::from(io.kind())),
65 Proto(proto) => Proto(proto.clone()),
66 SendError(e) => SendError(e.clone()),
67 Timeout => Timeout,
68 }
69 }
70}
71
72#[derive(Debug, Error, Clone)]
74pub struct Error {
75 kind: ErrorKind,
76 #[cfg(feature = "backtrace")]
77 backtrack: Option<ExtBacktrace>,
78}
79
80impl Error {
81 pub fn kind(&self) -> &ErrorKind {
83 &self.kind
84 }
85}
86
87impl fmt::Display for Error {
88 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89 cfg_if::cfg_if! {
90 if #[cfg(feature = "backtrace")] {
91 if let Some(ref backtrace) = self.backtrack {
92 fmt::Display::fmt(&self.kind, f)?;
93 fmt::Debug::fmt(backtrace, f)
94 } else {
95 fmt::Display::fmt(&self.kind, f)
96 }
97 } else {
98 fmt::Display::fmt(&self.kind, f)
99 }
100 }
101 }
102}
103
104impl From<ErrorKind> for Error {
105 fn from(kind: ErrorKind) -> Self {
106 Self {
107 kind,
108 #[cfg(feature = "backtrace")]
109 backtrack: trace!(),
110 }
111 }
112}
113
114impl From<&'static str> for Error {
115 fn from(msg: &'static str) -> Self {
116 ErrorKind::Message(msg).into()
117 }
118}
119
120impl From<mpsc::SendError> for Error {
121 fn from(e: mpsc::SendError) -> Self {
122 ErrorKind::from(e).into()
123 }
124}
125
126impl From<String> for Error {
127 fn from(msg: String) -> Self {
128 ErrorKind::Msg(msg).into()
129 }
130}
131
132impl From<DnsSecError> for Error {
133 fn from(e: DnsSecError) -> Self {
134 match *e.kind() {
135 DnsSecErrorKind::Timeout => ErrorKind::Timeout.into(),
136 _ => ErrorKind::from(e).into(),
137 }
138 }
139}
140
141impl From<io::Error> for Error {
142 fn from(e: io::Error) -> Self {
143 match e.kind() {
144 io::ErrorKind::TimedOut => ErrorKind::Timeout.into(),
145 _ => ErrorKind::from(e).into(),
146 }
147 }
148}
149
150impl From<ProtoError> for Error {
151 fn from(e: ProtoError) -> Self {
152 match *e.kind() {
153 ProtoErrorKind::Timeout => ErrorKind::Timeout.into(),
154 _ => ErrorKind::from(e).into(),
155 }
156 }
157}
158
159impl From<Error> for io::Error {
160 fn from(e: Error) -> Self {
161 match *e.kind() {
162 ErrorKind::Timeout => Self::new(io::ErrorKind::TimedOut, e),
163 _ => Self::new(io::ErrorKind::Other, e),
164 }
165 }
166}
167
168#[test]
169fn test_conversion() {
170 let io_error = io::Error::new(io::ErrorKind::TimedOut, "mock timeout");
171
172 let error = Error::from(io_error);
173
174 match *error.kind() {
175 ErrorKind::Timeout => (),
176 _ => panic!("incorrect type: {}", error),
177 }
178}