1use native_tls::Error as TlsError;
2use std::borrow::Cow;
3use std::error::Error as StdError;
4use std::fmt;
5use std::io::Error as IoError;
6use std::str::Utf8Error;
7use trust_dns_proto::error::ProtoError;
8use trust_dns_resolver::error::ResolveError;
9
10use xmpp_parsers::Error as ParsersError;
11use xmpp_parsers::sasl::DefinedCondition as SaslDefinedCondition;
12
13/// Top-level error type
14#[derive(Debug)]
15pub enum Error {
16 /// I/O error
17 Io(IoError),
18 /// Error resolving DNS and establishing a connection
19 Connection(ConnecterError),
20 /// DNS label conversion error, no details available from module
21 /// `idna`
22 Idna,
23 /// Protocol-level error
24 Protocol(ProtocolError),
25 /// Authentication error
26 Auth(AuthError),
27 /// TLS error
28 Tls(TlsError),
29 /// Connection closed
30 Disconnected,
31 /// Shoud never happen
32 InvalidState,
33}
34
35impl fmt::Display for Error {
36 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
37 match self {
38 Error::Io(e) => write!(fmt, "IO error: {}", e),
39 Error::Connection(e) => write!(fmt, "connection error: {}", e),
40 Error::Idna => write!(fmt, "IDNA error"),
41 Error::Protocol(e) => write!(fmt, "protocol error: {}", e),
42 Error::Auth(e) => write!(fmt, "authentication error: {}", e),
43 Error::Tls(e) => write!(fmt, "TLS error: {}", e),
44 Error::Disconnected => write!(fmt, "disconnected"),
45 Error::InvalidState => write!(fmt, "invalid state"),
46 }
47 }
48}
49
50impl From<IoError> for Error {
51 fn from(e: IoError) -> Self {
52 Error::Io(e)
53 }
54}
55
56impl From<ConnecterError> for Error {
57 fn from(e: ConnecterError) -> Self {
58 Error::Connection(e)
59 }
60}
61
62impl From<ProtocolError> for Error {
63 fn from(e: ProtocolError) -> Self {
64 Error::Protocol(e)
65 }
66}
67
68impl From<AuthError> for Error {
69 fn from(e: AuthError) -> Self {
70 Error::Auth(e)
71 }
72}
73
74impl From<TlsError> for Error {
75 fn from(e: TlsError) -> Self {
76 Error::Tls(e)
77 }
78}
79
80/// Causes for stream parsing errors
81#[derive(Debug)]
82pub enum ParserError {
83 /// Encoding error
84 Utf8(Utf8Error),
85 /// XML parse error
86 Parse(ParseError),
87 /// Illegal `</>`
88 ShortTag,
89 /// Required by `impl Decoder`
90 Io(IoError),
91}
92
93impl fmt::Display for ParserError {
94 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
95 match self {
96 ParserError::Utf8(e) => write!(fmt, "UTF-8 error: {}", e),
97 ParserError::Parse(e) => write!(fmt, "parse error: {}", e),
98 ParserError::ShortTag => write!(fmt, "short tag"),
99 ParserError::Io(e) => write!(fmt, "IO error: {}", e),
100 }
101 }
102}
103
104impl From<IoError> for ParserError {
105 fn from(e: IoError) -> Self {
106 ParserError::Io(e)
107 }
108}
109
110impl From<ParserError> for Error {
111 fn from(e: ParserError) -> Self {
112 ProtocolError::Parser(e).into()
113 }
114}
115
116/// XML parse error wrapper type
117#[derive(Debug)]
118pub struct ParseError(pub Cow<'static, str>);
119
120impl StdError for ParseError {
121 fn description(&self) -> &str {
122 self.0.as_ref()
123 }
124 fn cause(&self) -> Option<&dyn StdError> {
125 None
126 }
127}
128
129impl fmt::Display for ParseError {
130 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
131 write!(f, "{}", self.0)
132 }
133}
134
135/// XMPP protocol-level error
136#[derive(Debug)]
137pub enum ProtocolError {
138 /// XML parser error
139 Parser(ParserError),
140 /// Error with expected stanza schema
141 Parsers(ParsersError),
142 /// No TLS available
143 NoTls,
144 /// Invalid response to resource binding
145 InvalidBindResponse,
146 /// No xmlns attribute in <stream:stream>
147 NoStreamNamespace,
148 /// No id attribute in <stream:stream>
149 NoStreamId,
150 /// Encountered an unexpected XML token
151 InvalidToken,
152 /// Unexpected <stream:stream> (shouldn't occur)
153 InvalidStreamStart,
154}
155
156impl fmt::Display for ProtocolError {
157 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
158 match self {
159 ProtocolError::Parser(e) => write!(fmt, "XML parser error: {}", e),
160 ProtocolError::Parsers(e) => write!(fmt, "error with expected stanza schema: {}", e),
161 ProtocolError::NoTls => write!(fmt, "no TLS available"),
162 ProtocolError::InvalidBindResponse => write!(fmt, "invalid response to resource binding"),
163 ProtocolError::NoStreamNamespace => write!(fmt, "no xmlns attribute in <stream:stream>"),
164 ProtocolError::NoStreamId => write!(fmt, "no id attribute in <stream:stream>"),
165 ProtocolError::InvalidToken => write!(fmt, "encountered an unexpected XML token"),
166 ProtocolError::InvalidStreamStart => write!(fmt, "unexpected <stream:stream>"),
167 }
168 }
169}
170
171impl From<ParserError> for ProtocolError {
172 fn from(e: ParserError) -> Self {
173 ProtocolError::Parser(e)
174 }
175}
176
177impl From<ParsersError> for ProtocolError {
178 fn from(e: ParsersError) -> Self {
179 ProtocolError::Parsers(e)
180 }
181}
182
183/// Authentication error
184#[derive(Debug)]
185pub enum AuthError {
186 /// No matching SASL mechanism available
187 NoMechanism,
188 /// Local SASL implementation error
189 Sasl(String),
190 /// Failure from server
191 Fail(SaslDefinedCondition),
192 /// Component authentication failure
193 ComponentFail,
194}
195
196impl fmt::Display for AuthError {
197 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
198 match self {
199 AuthError::NoMechanism => write!(fmt, "no matching SASL mechanism available"),
200 AuthError::Sasl(s) => write!(fmt, "local SASL implementation error: {}", s),
201 AuthError::Fail(c) => write!(fmt, "failure from the server: {:?}", c),
202 AuthError::ComponentFail => write!(fmt, "component authentication failure"),
203 }
204 }
205}
206
207/// Error establishing connection
208#[derive(Debug)]
209pub enum ConnecterError {
210 /// All attempts failed, no error available
211 AllFailed,
212 /// DNS protocol error
213 Dns(ProtoError),
214 /// DNS resolution error
215 Resolve(ResolveError),
216}
217
218impl std::error::Error for ConnecterError {}
219
220impl std::fmt::Display for ConnecterError {
221 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
222 write!(fmt, "{:?}", self)
223 }
224}