2025-10-12 00:31:48 +02:00
|
|
|
use core::{fmt, net::AddrParseError, str::Utf8Error};
|
2024-08-05 15:09:59 +02:00
|
|
|
#[cfg(feature = "dns")]
|
2026-05-14 20:45:37 +02:00
|
|
|
use hickory_resolver::{net::NetError as DnsNetError, proto::ProtoError as DnsProtoError};
|
2020-12-26 20:11:23 +01:00
|
|
|
use sasl::client::MechanismError as SaslMechanismError;
|
2024-12-19 20:31:59 +01:00
|
|
|
use std::io;
|
2025-10-12 00:31:48 +02:00
|
|
|
use thiserror::Error;
|
2018-09-06 18:20:05 +02:00
|
|
|
|
2025-07-13 11:58:37 +02:00
|
|
|
use xmpp_parsers::stream_error::ReceivedStreamError;
|
|
|
|
|
|
2024-12-18 17:59:06 +01:00
|
|
|
use crate::{
|
|
|
|
|
connect::ServerConnectorError, jid, minidom,
|
2025-07-13 11:58:37 +02:00
|
|
|
parsers::sasl::DefinedCondition as SaslDefinedCondition, xmlstream::RecvFeaturesError,
|
2024-12-18 17:59:06 +01:00
|
|
|
};
|
2023-12-30 22:08:37 -05:00
|
|
|
|
2018-09-08 01:42:23 +02:00
|
|
|
/// Top-level error type
|
2025-10-12 00:31:48 +02:00
|
|
|
#[derive(Debug, Error)]
|
2018-09-06 17:46:06 +02:00
|
|
|
pub enum Error {
|
2018-09-08 01:42:23 +02:00
|
|
|
/// I/O error
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("I/O error: {0}")]
|
|
|
|
|
Io(#[from] io::Error),
|
2020-03-05 01:25:24 +01:00
|
|
|
/// Error parsing Jabber-Id
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("JID parse error: {0}")]
|
|
|
|
|
JidParse(#[from] jid::Error),
|
2018-09-08 01:42:23 +02:00
|
|
|
/// Protocol-level error
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("protocol error: {0}")]
|
|
|
|
|
Protocol(#[from] ProtocolError),
|
2018-09-08 01:42:23 +02:00
|
|
|
/// Authentication error
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("authentication error: {0}")]
|
|
|
|
|
Auth(#[from] AuthError),
|
2018-12-20 20:39:01 +01:00
|
|
|
/// Connection closed
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("disconnected")]
|
2018-12-20 20:39:01 +01:00
|
|
|
Disconnected,
|
2024-05-13 22:54:26 +02:00
|
|
|
/// Should never happen
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("invalid state")]
|
2018-09-06 17:46:06 +02:00
|
|
|
InvalidState,
|
2023-05-30 17:37:52 +02:00
|
|
|
/// Fmt error
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("fmt error: {0}")]
|
|
|
|
|
Fmt(#[from] fmt::Error),
|
2023-05-30 17:37:52 +02:00
|
|
|
/// Utf8 error
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("UTF-8 error: {0}")]
|
|
|
|
|
Utf8(#[from] Utf8Error),
|
2024-08-05 15:09:59 +02:00
|
|
|
/// Error specific to ServerConnector impl
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("connection error: {0}")]
|
2023-12-30 22:08:37 -05:00
|
|
|
Connection(Box<dyn ServerConnectorError>),
|
2024-08-05 15:09:59 +02:00
|
|
|
/// DNS protocol error
|
|
|
|
|
#[cfg(feature = "dns")]
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("{0:?}")]
|
2026-05-14 20:45:37 +02:00
|
|
|
DnsProto(#[from] DnsProtoError),
|
|
|
|
|
/// DNS network error
|
2024-08-05 15:09:59 +02:00
|
|
|
#[cfg(feature = "dns")]
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("{0:?}")]
|
2026-05-14 20:45:37 +02:00
|
|
|
DnsNet(#[from] DnsNetError),
|
2024-08-05 15:09:59 +02:00
|
|
|
/// DNS label conversion error, no details available from module
|
|
|
|
|
/// `idna`
|
|
|
|
|
#[cfg(feature = "dns")]
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("IDNA error")]
|
2024-08-05 15:09:59 +02:00
|
|
|
Idna,
|
2024-08-06 20:40:24 +02:00
|
|
|
/// Invalid IP/Port address
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("wrong network address: {0}")]
|
|
|
|
|
Addr(#[from] AddrParseError),
|
2025-07-13 11:58:37 +02:00
|
|
|
/// Received a stream error
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("{0}")]
|
2025-07-13 11:58:37 +02:00
|
|
|
StreamError(ReceivedStreamError),
|
2018-09-06 17:46:06 +02:00
|
|
|
}
|
|
|
|
|
|
2023-12-30 22:08:37 -05:00
|
|
|
impl<T: ServerConnectorError + 'static> From<T> for Error {
|
|
|
|
|
fn from(e: T) -> Self {
|
|
|
|
|
Error::Connection(Box::new(e))
|
2019-09-05 22:25:28 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-05 15:09:59 +02:00
|
|
|
#[cfg(feature = "dns")]
|
|
|
|
|
impl From<idna::Errors> for Error {
|
|
|
|
|
fn from(_e: idna::Errors) -> Self {
|
|
|
|
|
Error::Idna
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-13 11:58:37 +02:00
|
|
|
impl From<RecvFeaturesError> for Error {
|
|
|
|
|
fn from(e: RecvFeaturesError) -> Self {
|
|
|
|
|
match e {
|
|
|
|
|
RecvFeaturesError::Io(e) => e.into(),
|
|
|
|
|
RecvFeaturesError::StreamError(e) => Self::StreamError(e),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-08 01:42:23 +02:00
|
|
|
/// XMPP protocol-level error
|
2025-10-12 00:31:48 +02:00
|
|
|
#[derive(Debug, Error)]
|
2018-09-06 17:46:06 +02:00
|
|
|
pub enum ProtocolError {
|
2018-09-08 01:42:23 +02:00
|
|
|
/// XML parser error
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("XML parser error: {0}")]
|
|
|
|
|
Parser(#[from] minidom::Error),
|
2018-09-08 01:42:23 +02:00
|
|
|
/// Error with expected stanza schema
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("error with expected stanza schema: {0}")]
|
|
|
|
|
Parsers(#[from] xso::error::Error),
|
2018-09-08 01:42:23 +02:00
|
|
|
/// No TLS available
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("no TLS available")]
|
2018-09-06 17:46:06 +02:00
|
|
|
NoTls,
|
2018-09-08 01:42:23 +02:00
|
|
|
/// Invalid response to resource binding
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("invalid response to resource binding")]
|
2018-09-06 17:46:06 +02:00
|
|
|
InvalidBindResponse,
|
2018-09-08 01:42:23 +02:00
|
|
|
/// No xmlns attribute in <stream:stream>
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("no xmlns attribute in <stream:stream>")]
|
2018-09-06 17:46:06 +02:00
|
|
|
NoStreamNamespace,
|
2018-09-08 01:42:23 +02:00
|
|
|
/// No id attribute in <stream:stream>
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("no id attribute in <stream:stream>")]
|
2018-09-06 17:46:06 +02:00
|
|
|
NoStreamId,
|
2018-09-08 01:42:23 +02:00
|
|
|
/// Encountered an unexpected XML token
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("encountered an unexpected XML token")]
|
2018-09-06 17:46:06 +02:00
|
|
|
InvalidToken,
|
2019-01-26 21:07:15 +01:00
|
|
|
/// Unexpected <stream:stream> (shouldn't occur)
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("unexpected <stream:stream>")]
|
2019-01-26 21:07:15 +01:00
|
|
|
InvalidStreamStart,
|
2018-09-06 17:46:06 +02:00
|
|
|
}
|
|
|
|
|
|
2018-09-08 01:42:23 +02:00
|
|
|
/// Authentication error
|
2025-10-12 00:31:48 +02:00
|
|
|
#[derive(Debug, Error)]
|
2018-09-06 17:46:06 +02:00
|
|
|
pub enum AuthError {
|
2018-09-08 01:42:23 +02:00
|
|
|
/// No matching SASL mechanism available
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("no matching SASL mechanism available")]
|
2018-09-06 17:46:06 +02:00
|
|
|
NoMechanism,
|
2018-09-08 01:42:23 +02:00
|
|
|
/// Local SASL implementation error
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("local SASL implementation error: {0}")]
|
2020-12-26 20:11:23 +01:00
|
|
|
Sasl(SaslMechanismError),
|
2018-09-08 01:42:23 +02:00
|
|
|
/// Failure from server
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("failure from the server: {0:?}")]
|
2018-09-06 17:46:06 +02:00
|
|
|
Fail(SaslDefinedCondition),
|
2018-09-08 01:42:23 +02:00
|
|
|
/// Component authentication failure
|
2025-10-12 00:31:48 +02:00
|
|
|
#[error("component authentication failure")]
|
2018-09-06 17:46:06 +02:00
|
|
|
ComponentFail,
|
|
|
|
|
}
|