2018-01-28 00:52:11 +01:00
|
|
|
//! Errors for `irc` crate using `failure`.
|
|
|
|
|
|
|
|
use std::io::Error as IoError;
|
|
|
|
use std::sync::mpsc::RecvError;
|
|
|
|
|
2019-08-27 15:05:51 +02:00
|
|
|
use futures_channel::{
|
|
|
|
mpsc::{SendError, TrySendError},
|
|
|
|
oneshot::Canceled,
|
|
|
|
};
|
2019-10-16 03:12:29 +02:00
|
|
|
use thiserror::Error;
|
2018-01-28 00:52:11 +01:00
|
|
|
|
2020-03-07 13:17:35 +08:00
|
|
|
#[cfg(feature = "tls-rust")]
|
|
|
|
use tokio_rustls::webpki::InvalidDNSNameError;
|
|
|
|
|
2019-08-27 15:05:51 +02:00
|
|
|
use crate::proto::error::{MessageParseError, ProtocolError};
|
2018-01-28 00:52:11 +01:00
|
|
|
|
|
|
|
/// A specialized `Result` type for the `irc` crate.
|
2019-10-16 03:12:29 +02:00
|
|
|
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
2018-01-28 00:52:11 +01:00
|
|
|
|
|
|
|
/// The main crate-wide error type.
|
2019-10-16 03:12:29 +02:00
|
|
|
#[derive(Debug, Error)]
|
2019-08-27 15:05:51 +02:00
|
|
|
pub enum Error {
|
2018-01-28 00:52:11 +01:00
|
|
|
/// An internal I/O error.
|
2019-10-16 03:12:29 +02:00
|
|
|
#[error("an io error occurred")]
|
|
|
|
Io(#[source] IoError),
|
2018-01-28 00:52:11 +01:00
|
|
|
|
2020-03-04 14:38:01 +08:00
|
|
|
/// An internal proxy error.
|
|
|
|
#[cfg(feature = "proxy")]
|
|
|
|
#[error("a proxy error occurred")]
|
|
|
|
Proxy(tokio_socks::Error),
|
|
|
|
|
2018-01-28 00:52:11 +01:00
|
|
|
/// An internal TLS error.
|
2020-03-07 13:17:35 +08:00
|
|
|
#[cfg(feature = "tls-native")]
|
2019-10-16 03:12:29 +02:00
|
|
|
#[error("a TLS error occurred")]
|
|
|
|
Tls(#[source] native_tls::Error),
|
2018-01-28 00:52:11 +01:00
|
|
|
|
2020-03-07 13:17:35 +08:00
|
|
|
/// An internal DNS error.
|
|
|
|
#[cfg(feature = "tls-rust")]
|
|
|
|
#[error("a DNS error occurred")]
|
|
|
|
Dns(#[source] InvalidDNSNameError),
|
|
|
|
|
2018-01-28 00:52:11 +01:00
|
|
|
/// An internal synchronous channel closed.
|
2019-10-16 03:12:29 +02:00
|
|
|
#[error("a sync channel closed")]
|
|
|
|
SyncChannelClosed(#[source] RecvError),
|
2018-01-28 00:52:11 +01:00
|
|
|
|
|
|
|
/// An internal asynchronous channel closed.
|
2019-10-16 03:12:29 +02:00
|
|
|
#[error("an async channel closed")]
|
|
|
|
AsyncChannelClosed(#[source] SendError),
|
2018-01-28 00:52:11 +01:00
|
|
|
|
|
|
|
/// An internal oneshot channel closed.
|
2019-10-16 03:12:29 +02:00
|
|
|
#[error("a oneshot channel closed")]
|
|
|
|
OneShotCanceled(#[source] Canceled),
|
2018-01-28 00:52:11 +01:00
|
|
|
|
|
|
|
/// Error for invalid configurations.
|
2019-10-16 03:12:29 +02:00
|
|
|
#[error("invalid config: {}", path)]
|
2018-01-28 00:52:11 +01:00
|
|
|
InvalidConfig {
|
|
|
|
/// The path to the configuration, or "<none>" if none specified.
|
|
|
|
path: String,
|
|
|
|
/// The detailed configuration error.
|
2019-10-16 03:12:29 +02:00
|
|
|
#[source]
|
2018-01-28 00:52:11 +01:00
|
|
|
cause: ConfigError,
|
|
|
|
},
|
|
|
|
|
|
|
|
/// Error for invalid messages.
|
2019-10-16 03:12:29 +02:00
|
|
|
#[error("invalid message: {}", string)]
|
2018-01-28 00:52:11 +01:00
|
|
|
InvalidMessage {
|
|
|
|
/// The string that failed to parse.
|
|
|
|
string: String,
|
|
|
|
/// The detailed message parsing error.
|
2019-10-16 03:12:29 +02:00
|
|
|
#[source]
|
2018-01-28 00:52:11 +01:00
|
|
|
cause: MessageParseError,
|
|
|
|
},
|
|
|
|
|
|
|
|
/// Mutex for a logged transport was poisoned making the log inaccessible.
|
2019-10-16 03:12:29 +02:00
|
|
|
#[error("mutex for a logged transport was poisoned")]
|
2018-01-28 00:52:11 +01:00
|
|
|
PoisonedLog,
|
|
|
|
|
|
|
|
/// Ping timed out due to no response.
|
2019-10-16 03:12:29 +02:00
|
|
|
#[error("connection reset: no ping response")]
|
2018-01-28 00:52:11 +01:00
|
|
|
PingTimeout,
|
|
|
|
|
|
|
|
/// Failed to lookup an unknown codec.
|
2019-10-16 03:12:29 +02:00
|
|
|
#[error("unknown codec: {}", codec)]
|
2018-01-28 00:52:11 +01:00
|
|
|
UnknownCodec {
|
|
|
|
/// The attempted codec.
|
|
|
|
codec: String,
|
|
|
|
},
|
|
|
|
|
|
|
|
/// Failed to encode or decode something with the given codec.
|
2019-10-16 03:12:29 +02:00
|
|
|
#[error("codec {} failed: {}", codec, data)]
|
2018-01-28 00:52:11 +01:00
|
|
|
CodecFailed {
|
|
|
|
/// The canonical codec name.
|
|
|
|
codec: &'static str,
|
|
|
|
/// The data that failed to encode or decode.
|
|
|
|
data: String,
|
|
|
|
},
|
2018-02-12 19:16:00 +00:00
|
|
|
|
2018-02-12 20:30:02 +01:00
|
|
|
/// All specified nicknames were in use or unusable.
|
2019-10-16 03:12:29 +02:00
|
|
|
#[error("none of the specified nicknames were usable")]
|
2018-02-21 14:30:27 +01:00
|
|
|
NoUsableNick,
|
|
|
|
|
2019-08-27 15:05:51 +02:00
|
|
|
/// Stream has already been configured.
|
2019-10-16 03:12:29 +02:00
|
|
|
#[error("stream has already been configured")]
|
2019-08-27 15:05:51 +02:00
|
|
|
StreamAlreadyConfigured,
|
2018-01-28 00:52:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Errors that occur with configurations.
|
2019-10-16 03:12:29 +02:00
|
|
|
#[derive(Debug, Error)]
|
2018-01-28 00:52:11 +01:00
|
|
|
pub enum ConfigError {
|
|
|
|
/// Failed to parse as TOML.
|
2020-01-28 17:58:38 -08:00
|
|
|
#[cfg(feature = "toml_config")]
|
2019-10-16 03:12:29 +02:00
|
|
|
#[error("invalid toml")]
|
|
|
|
InvalidToml(#[source] TomlError),
|
2018-01-28 00:52:11 +01:00
|
|
|
|
|
|
|
/// Failed to parse as JSON.
|
2020-01-28 17:58:38 -08:00
|
|
|
#[cfg(feature = "json_config")]
|
2019-10-16 03:12:29 +02:00
|
|
|
#[error("invalid json")]
|
|
|
|
InvalidJson(#[source] serde_json::Error),
|
2018-01-28 00:52:11 +01:00
|
|
|
|
|
|
|
/// Failed to parse as YAML.
|
2020-01-28 17:58:38 -08:00
|
|
|
#[cfg(feature = "yaml_config")]
|
2019-10-16 03:12:29 +02:00
|
|
|
#[error("invalid yaml")]
|
|
|
|
InvalidYaml(#[source] serde_yaml::Error),
|
2018-01-28 00:52:11 +01:00
|
|
|
|
|
|
|
/// Failed to parse the given format because it was disabled at compile-time.
|
2019-10-16 03:12:29 +02:00
|
|
|
#[error("config format disabled: {}", format)]
|
2018-01-28 00:52:11 +01:00
|
|
|
ConfigFormatDisabled {
|
|
|
|
/// The disabled file format.
|
|
|
|
format: &'static str,
|
|
|
|
},
|
|
|
|
|
|
|
|
/// Could not identify the given file format.
|
2019-10-16 03:12:29 +02:00
|
|
|
#[error("config format unknown: {}", format)]
|
2018-01-28 00:52:11 +01:00
|
|
|
UnknownConfigFormat {
|
|
|
|
/// The unknown file extension.
|
|
|
|
format: String,
|
|
|
|
},
|
|
|
|
|
|
|
|
/// File was missing an extension to identify file format.
|
2019-10-16 03:12:29 +02:00
|
|
|
#[error("missing format extension")]
|
2018-01-28 00:52:11 +01:00
|
|
|
MissingExtension,
|
|
|
|
|
|
|
|
/// Configuration does not specify a nickname.
|
2019-10-16 03:12:29 +02:00
|
|
|
#[error("nickname not specified")]
|
2018-01-28 00:52:11 +01:00
|
|
|
NicknameNotSpecified,
|
|
|
|
|
|
|
|
/// Configuration does not specify a server.
|
2019-10-16 03:12:29 +02:00
|
|
|
#[error("server not specified")]
|
2018-01-28 00:52:11 +01:00
|
|
|
ServerNotSpecified,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A wrapper that combines toml's serialization and deserialization errors.
|
2020-01-28 17:58:38 -08:00
|
|
|
#[cfg(feature = "toml_config")]
|
2019-10-16 03:12:29 +02:00
|
|
|
#[derive(Debug, Error)]
|
2018-01-28 00:52:11 +01:00
|
|
|
pub enum TomlError {
|
|
|
|
/// A TOML deserialization error.
|
2019-10-16 03:12:29 +02:00
|
|
|
#[error("deserialization failed")]
|
|
|
|
Read(#[source] toml::de::Error),
|
2018-01-28 00:52:11 +01:00
|
|
|
/// A TOML serialization error.
|
2019-10-16 03:12:29 +02:00
|
|
|
#[error("serialization failed")]
|
|
|
|
Write(#[source] toml::ser::Error),
|
2018-01-28 00:52:11 +01:00
|
|
|
}
|
|
|
|
|
2019-08-27 15:05:51 +02:00
|
|
|
impl From<ProtocolError> for Error {
|
|
|
|
fn from(e: ProtocolError) -> Error {
|
2018-03-10 15:48:06 +01:00
|
|
|
match e {
|
2019-08-27 15:05:51 +02:00
|
|
|
ProtocolError::Io(e) => Error::Io(e),
|
|
|
|
ProtocolError::InvalidMessage { string, cause } => {
|
|
|
|
Error::InvalidMessage { string, cause }
|
|
|
|
}
|
2018-03-10 15:48:06 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-27 15:05:51 +02:00
|
|
|
impl From<IoError> for Error {
|
|
|
|
fn from(e: IoError) -> Error {
|
|
|
|
Error::Io(e)
|
2018-01-28 00:52:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-04 14:38:01 +08:00
|
|
|
#[cfg(feature = "proxy")]
|
|
|
|
impl From<tokio_socks::Error> for Error {
|
|
|
|
fn from(e: tokio_socks::Error) -> Error {
|
|
|
|
Error::Proxy(e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-07 13:17:35 +08:00
|
|
|
#[cfg(feature = "tls-native")]
|
2019-10-16 03:12:29 +02:00
|
|
|
impl From<native_tls::Error> for Error {
|
|
|
|
fn from(e: native_tls::Error) -> Error {
|
2019-08-27 15:05:51 +02:00
|
|
|
Error::Tls(e)
|
2019-06-10 20:52:36 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-07 13:17:35 +08:00
|
|
|
#[cfg(feature = "tls-rust")]
|
|
|
|
impl From<InvalidDNSNameError> for Error {
|
|
|
|
fn from(e: InvalidDNSNameError) -> Error {
|
|
|
|
Error::Dns(e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-27 15:05:51 +02:00
|
|
|
impl From<RecvError> for Error {
|
|
|
|
fn from(e: RecvError) -> Error {
|
|
|
|
Error::SyncChannelClosed(e)
|
2018-01-28 00:52:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-27 15:05:51 +02:00
|
|
|
impl From<SendError> for Error {
|
|
|
|
fn from(e: SendError) -> Error {
|
|
|
|
Error::AsyncChannelClosed(e)
|
2018-01-28 00:52:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-27 15:05:51 +02:00
|
|
|
impl<T> From<TrySendError<T>> for Error {
|
|
|
|
fn from(e: TrySendError<T>) -> Error {
|
|
|
|
Error::AsyncChannelClosed(e.into_send_error())
|
2018-01-28 00:52:11 +01:00
|
|
|
}
|
|
|
|
}
|
2017-06-20 14:54:06 -04:00
|
|
|
|
2019-08-27 15:05:51 +02:00
|
|
|
impl From<Canceled> for Error {
|
|
|
|
fn from(e: Canceled) -> Error {
|
|
|
|
Error::OneShotCanceled(e)
|
2017-06-20 14:54:06 -04:00
|
|
|
}
|
|
|
|
}
|