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, Error)]
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
35/// Causes for stream parsing errors
36#[derive(Debug, Error)]
37pub enum ParserError {
38 /// Encoding error
39 Utf8(Utf8Error),
40 /// XML parse error
41 Parse(ParseError),
42 /// Illegal `</>`
43 ShortTag,
44 /// Required by `impl Decoder`
45 IO(IoError),
46}
47
48impl From<ParserError> for Error {
49 fn from(e: ParserError) -> Self {
50 ProtocolError::Parser(e).into()
51 }
52}
53
54/// XML parse error wrapper type
55#[derive(Debug)]
56pub struct ParseError(pub Cow<'static, str>);
57
58impl StdError for ParseError {
59 fn description(&self) -> &str {
60 self.0.as_ref()
61 }
62 fn cause(&self) -> Option<&StdError> {
63 None
64 }
65}
66
67impl fmt::Display for ParseError {
68 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
69 write!(f, "{}", self.0)
70 }
71}
72
73/// XMPP protocol-level error
74#[derive(Debug, Error)]
75pub enum ProtocolError {
76 /// XML parser error
77 Parser(ParserError),
78 /// Error with expected stanza schema
79 #[error(non_std)]
80 Parsers(ParsersError),
81 /// No TLS available
82 NoTls,
83 /// Invalid response to resource binding
84 InvalidBindResponse,
85 /// No xmlns attribute in <stream:stream>
86 NoStreamNamespace,
87 /// No id attribute in <stream:stream>
88 NoStreamId,
89 /// Encountered an unexpected XML token
90 InvalidToken,
91 /// Unexpected <stream:stream> (shouldn't occur)
92 InvalidStreamStart,
93}
94
95/// Authentication error
96#[derive(Debug, Error)]
97pub enum AuthError {
98 /// No matching SASL mechanism available
99 NoMechanism,
100 /// Local SASL implementation error
101 #[error(no_from, non_std, msg_embedded)]
102 Sasl(String),
103 /// Failure from server
104 #[error(non_std)]
105 Fail(SaslDefinedCondition),
106 /// Component authentication failure
107 #[error(no_from)]
108 ComponentFail,
109}
110
111/// Error establishing connection
112#[derive(Debug)]
113pub enum ConnecterError {
114 /// All attempts failed, no error available
115 AllFailed,
116 /// DNS protocol error
117 Dns(ProtoError),
118 /// DNS resolution error
119 Resolve(ResolveError),
120}
121
122impl std::error::Error for ConnecterError {}
123
124impl std::fmt::Display for ConnecterError {
125 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
126 write!(fmt, "{:?}", self)
127 }
128}