1use core::{fmt, net::AddrParseError, str::Utf8Error};
2#[cfg(feature = "dns")]
3use hickory_resolver::{proto::ProtoError as DnsProtoError, ResolveError as DnsResolveError};
4use sasl::client::MechanismError as SaslMechanismError;
5use std::io;
6use thiserror::Error;
7
8use xmpp_parsers::stream_error::ReceivedStreamError;
9
10use crate::{
11 connect::ServerConnectorError, jid, minidom,
12 parsers::sasl::DefinedCondition as SaslDefinedCondition, xmlstream::RecvFeaturesError,
13};
14
15#[derive(Debug, Error)]
17pub enum Error {
18 #[error("I/O error: {0}")]
20 Io(#[from] io::Error),
21 #[error("JID parse error: {0}")]
23 JidParse(#[from] jid::Error),
24 #[error("protocol error: {0}")]
26 Protocol(#[from] ProtocolError),
27 #[error("authentication error: {0}")]
29 Auth(#[from] AuthError),
30 #[error("disconnected")]
32 Disconnected,
33 #[error("invalid state")]
35 InvalidState,
36 #[error("fmt error: {0}")]
38 Fmt(#[from] fmt::Error),
39 #[error("UTF-8 error: {0}")]
41 Utf8(#[from] Utf8Error),
42 #[error("connection error: {0}")]
44 Connection(Box<dyn ServerConnectorError>),
45 #[cfg(feature = "dns")]
47 #[error("{0:?}")]
48 Dns(#[from] DnsProtoError),
49 #[cfg(feature = "dns")]
51 #[error("{0:?}")]
52 Resolve(#[from] DnsResolveError),
53 #[cfg(feature = "dns")]
56 #[error("IDNA error")]
57 Idna,
58 #[error("wrong network address: {0}")]
60 Addr(#[from] AddrParseError),
61 #[error("{0}")]
63 StreamError(ReceivedStreamError),
64}
65
66impl<T: ServerConnectorError + 'static> From<T> for Error {
67 fn from(e: T) -> Self {
68 Error::Connection(Box::new(e))
69 }
70}
71
72#[cfg(feature = "dns")]
73impl From<idna::Errors> for Error {
74 fn from(_e: idna::Errors) -> Self {
75 Error::Idna
76 }
77}
78
79impl From<RecvFeaturesError> for Error {
80 fn from(e: RecvFeaturesError) -> Self {
81 match e {
82 RecvFeaturesError::Io(e) => e.into(),
83 RecvFeaturesError::StreamError(e) => Self::StreamError(e),
84 }
85 }
86}
87
88#[derive(Debug, Error)]
90pub enum ProtocolError {
91 #[error("XML parser error: {0}")]
93 Parser(#[from] minidom::Error),
94 #[error("error with expected stanza schema: {0}")]
96 Parsers(#[from] xso::error::Error),
97 #[error("no TLS available")]
99 NoTls,
100 #[error("invalid response to resource binding")]
102 InvalidBindResponse,
103 #[error("no xmlns attribute in <stream:stream>")]
105 NoStreamNamespace,
106 #[error("no id attribute in <stream:stream>")]
108 NoStreamId,
109 #[error("encountered an unexpected XML token")]
111 InvalidToken,
112 #[error("unexpected <stream:stream>")]
114 InvalidStreamStart,
115}
116
117#[derive(Debug, Error)]
119pub enum AuthError {
120 #[error("no matching SASL mechanism available")]
122 NoMechanism,
123 #[error("local SASL implementation error: {0}")]
125 Sasl(SaslMechanismError),
126 #[error("failure from the server: {0:?}")]
128 Fail(SaslDefinedCondition),
129 #[error("component authentication failure")]
131 ComponentFail,
132}