xmpp-rs/tokio-xmpp/src/error.rs

249 lines
7 KiB
Rust
Raw Normal View History

use hickory_resolver::{error::ResolveError, proto::error::ProtoError};
#[cfg(feature = "tls-native")]
2018-12-18 18:04:31 +00:00
use native_tls::Error as TlsError;
2020-12-26 19:11:23 +00:00
use sasl::client::MechanismError as SaslMechanismError;
2018-09-06 15:46:06 +00:00
use std::borrow::Cow;
2018-12-18 18:04:31 +00:00
use std::error::Error as StdError;
2018-09-06 15:46:06 +00:00
use std::fmt;
2018-12-18 18:04:31 +00:00
use std::io::Error as IoError;
use std::str::Utf8Error;
#[cfg(all(feature = "tls-rust", not(feature = "tls-native")))]
use tokio_rustls::rustls::client::InvalidDnsNameError;
#[cfg(all(feature = "tls-rust", not(feature = "tls-native")))]
use tokio_rustls::rustls::Error as TlsError;
2018-09-06 16:20:05 +00:00
2018-09-06 15:46:06 +00:00
use xmpp_parsers::sasl::DefinedCondition as SaslDefinedCondition;
2020-03-05 00:25:24 +00:00
use xmpp_parsers::{Error as ParsersError, JidParseError};
2018-09-06 15:46:06 +00:00
2018-09-07 23:42:23 +00:00
/// Top-level error type
#[derive(Debug)]
2018-09-06 15:46:06 +00:00
pub enum Error {
2018-09-07 23:42:23 +00:00
/// I/O error
2018-09-06 15:46:06 +00:00
Io(IoError),
2018-09-07 23:42:23 +00:00
/// Error resolving DNS and establishing a connection
2018-09-06 15:46:06 +00:00
Connection(ConnecterError),
/// DNS label conversion error, no details available from module
/// `idna`
Idna,
2020-03-05 00:25:24 +00:00
/// Error parsing Jabber-Id
JidParse(JidParseError),
2018-09-07 23:42:23 +00:00
/// Protocol-level error
2018-09-06 15:46:06 +00:00
Protocol(ProtocolError),
2018-09-07 23:42:23 +00:00
/// Authentication error
2018-09-06 15:46:06 +00:00
Auth(AuthError),
2018-09-07 23:42:23 +00:00
/// TLS error
2018-09-06 15:46:06 +00:00
Tls(TlsError),
#[cfg(all(feature = "tls-rust", not(feature = "tls-native")))]
/// DNS name parsing error
DnsNameError(InvalidDnsNameError),
2018-12-20 19:39:01 +00:00
/// Connection closed
Disconnected,
2018-09-06 15:46:06 +00:00
/// Shoud never happen
InvalidState,
/// Fmt error
Fmt(fmt::Error),
/// Utf8 error
Utf8(Utf8Error),
2018-09-06 15:46:06 +00:00
}
impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::Io(e) => write!(fmt, "IO error: {}", e),
Error::Connection(e) => write!(fmt, "connection error: {}", e),
Error::Idna => write!(fmt, "IDNA error"),
2020-03-05 00:25:24 +00:00
Error::JidParse(e) => write!(fmt, "jid parse error: {}", e),
Error::Protocol(e) => write!(fmt, "protocol error: {}", e),
Error::Auth(e) => write!(fmt, "authentication error: {}", e),
Error::Tls(e) => write!(fmt, "TLS error: {}", e),
#[cfg(all(feature = "tls-rust", not(feature = "tls-native")))]
Error::DnsNameError(e) => write!(fmt, "DNS name error: {}", e),
Error::Disconnected => write!(fmt, "disconnected"),
Error::InvalidState => write!(fmt, "invalid state"),
Error::Fmt(e) => write!(fmt, "Fmt error: {}", e),
Error::Utf8(e) => write!(fmt, "Utf8 error: {}", e),
}
}
}
impl StdError for Error {}
impl From<IoError> for Error {
fn from(e: IoError) -> Self {
Error::Io(e)
}
}
impl From<ConnecterError> for Error {
fn from(e: ConnecterError) -> Self {
Error::Connection(e)
}
}
2020-03-05 00:25:24 +00:00
impl From<JidParseError> for Error {
fn from(e: JidParseError) -> Self {
Error::JidParse(e)
}
}
impl From<ProtocolError> for Error {
fn from(e: ProtocolError) -> Self {
Error::Protocol(e)
}
}
impl From<AuthError> for Error {
fn from(e: AuthError) -> Self {
Error::Auth(e)
}
}
impl From<TlsError> for Error {
fn from(e: TlsError) -> Self {
Error::Tls(e)
}
}
impl From<fmt::Error> for Error {
fn from(e: fmt::Error) -> Self {
Error::Fmt(e)
}
}
impl From<Utf8Error> for Error {
fn from(e: Utf8Error) -> Self {
Error::Utf8(e)
}
}
#[cfg(all(feature = "tls-rust", not(feature = "tls-native")))]
impl From<InvalidDnsNameError> for Error {
fn from(e: InvalidDnsNameError) -> Self {
Error::DnsNameError(e)
}
}
2018-09-06 15:46:06 +00:00
/// XML parse error wrapper type
#[derive(Debug)]
pub struct ParseError(pub Cow<'static, str>);
impl StdError for ParseError {
fn description(&self) -> &str {
self.0.as_ref()
}
fn cause(&self) -> Option<&dyn StdError> {
2018-09-06 15:46:06 +00:00
None
}
}
impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
2018-09-07 23:42:23 +00:00
/// XMPP protocol-level error
#[derive(Debug)]
2018-09-06 15:46:06 +00:00
pub enum ProtocolError {
2018-09-07 23:42:23 +00:00
/// XML parser error
Parser(minidom::Error),
2018-09-07 23:42:23 +00:00
/// Error with expected stanza schema
2018-09-06 15:46:06 +00:00
Parsers(ParsersError),
2018-09-07 23:42:23 +00:00
/// No TLS available
2018-09-06 15:46:06 +00:00
NoTls,
2018-09-07 23:42:23 +00:00
/// Invalid response to resource binding
2018-09-06 15:46:06 +00:00
InvalidBindResponse,
2018-09-07 23:42:23 +00:00
/// No xmlns attribute in <stream:stream>
2018-09-06 15:46:06 +00:00
NoStreamNamespace,
2018-09-07 23:42:23 +00:00
/// No id attribute in <stream:stream>
2018-09-06 15:46:06 +00:00
NoStreamId,
2018-09-07 23:42:23 +00:00
/// Encountered an unexpected XML token
2018-09-06 15:46:06 +00:00
InvalidToken,
2019-01-26 20:07:15 +00:00
/// Unexpected <stream:stream> (shouldn't occur)
InvalidStreamStart,
2018-09-06 15:46:06 +00:00
}
impl fmt::Display for ProtocolError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self {
ProtocolError::Parser(e) => write!(fmt, "XML parser error: {}", e),
ProtocolError::Parsers(e) => write!(fmt, "error with expected stanza schema: {}", e),
ProtocolError::NoTls => write!(fmt, "no TLS available"),
ProtocolError::InvalidBindResponse => {
write!(fmt, "invalid response to resource binding")
}
ProtocolError::NoStreamNamespace => {
write!(fmt, "no xmlns attribute in <stream:stream>")
}
ProtocolError::NoStreamId => write!(fmt, "no id attribute in <stream:stream>"),
ProtocolError::InvalidToken => write!(fmt, "encountered an unexpected XML token"),
ProtocolError::InvalidStreamStart => write!(fmt, "unexpected <stream:stream>"),
}
}
}
impl StdError for ProtocolError {}
impl From<minidom::Error> for ProtocolError {
fn from(e: minidom::Error) -> Self {
ProtocolError::Parser(e)
}
}
impl From<minidom::Error> for Error {
fn from(e: minidom::Error) -> Self {
ProtocolError::Parser(e).into()
}
}
impl From<ParsersError> for ProtocolError {
fn from(e: ParsersError) -> Self {
ProtocolError::Parsers(e)
}
}
2018-09-07 23:42:23 +00:00
/// Authentication error
#[derive(Debug)]
2018-09-06 15:46:06 +00:00
pub enum AuthError {
2018-09-07 23:42:23 +00:00
/// No matching SASL mechanism available
2018-09-06 15:46:06 +00:00
NoMechanism,
2018-09-07 23:42:23 +00:00
/// Local SASL implementation error
2020-12-26 19:11:23 +00:00
Sasl(SaslMechanismError),
2018-09-07 23:42:23 +00:00
/// Failure from server
2018-09-06 15:46:06 +00:00
Fail(SaslDefinedCondition),
2018-09-07 23:42:23 +00:00
/// Component authentication failure
2018-09-06 15:46:06 +00:00
ComponentFail,
}
impl StdError for AuthError {}
impl fmt::Display for AuthError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self {
AuthError::NoMechanism => write!(fmt, "no matching SASL mechanism available"),
AuthError::Sasl(s) => write!(fmt, "local SASL implementation error: {}", s),
AuthError::Fail(c) => write!(fmt, "failure from the server: {:?}", c),
AuthError::ComponentFail => write!(fmt, "component authentication failure"),
}
}
}
2018-09-07 23:42:23 +00:00
/// Error establishing connection
#[derive(Debug)]
2018-09-06 15:46:06 +00:00
pub enum ConnecterError {
2018-09-07 23:42:23 +00:00
/// All attempts failed, no error available
2018-09-06 15:46:06 +00:00
AllFailed,
2018-09-07 23:42:23 +00:00
/// DNS protocol error
2018-09-06 16:20:05 +00:00
Dns(ProtoError),
/// DNS resolution error
Resolve(ResolveError),
}
impl StdError for ConnecterError {}
impl std::fmt::Display for ConnecterError {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(fmt, "{:?}", self)
}
}