1use std::io::Error as IoError;
4use std::sync::mpsc::RecvError;
5
6use thiserror::Error;
7use tokio::sync::mpsc::error::{SendError, TrySendError};
8#[cfg(feature = "tls-rust")]
9use tokio_rustls::rustls::pki_types::InvalidDnsNameError;
10
11use crate::proto::error::{MessageParseError, ProtocolError};
12
13pub type Result<T, E = Error> = std::result::Result<T, E>;
15
16#[derive(Debug, Error)]
18pub enum Error {
19 #[error("an io error occurred")]
21 Io(
22 #[source]
23 #[from]
24 IoError,
25 ),
26
27 #[cfg(feature = "proxy")]
29 #[error("a proxy error occurred")]
30 Proxy(#[from] tokio_socks::Error),
31
32 #[cfg(all(feature = "tls-native", not(feature = "tls-rust")))]
34 #[error("a TLS error occurred: {0}")]
35 Tls(
36 #[source]
37 #[from]
38 native_tls::Error,
39 ),
40
41 #[cfg(feature = "tls-rust")]
43 #[error("a TLS error occurred")]
44 Tls(
45 #[source]
46 #[from]
47 tokio_rustls::rustls::Error,
48 ),
49
50 #[cfg(feature = "tls-rust")]
52 #[error("invalid DNS name")]
53 InvalidDnsNameError(
54 #[source]
55 #[from]
56 InvalidDnsNameError,
57 ),
58
59 #[error("a sync channel closed")]
61 SyncChannelClosed(
62 #[source]
63 #[from]
64 RecvError,
65 ),
66
67 #[error("an async channel closed")]
69 AsyncChannelClosed,
70
71 #[error("a oneshot channel closed")]
73 OneShotCanceled,
74
75 #[error("invalid config: {}", path)]
77 InvalidConfig {
78 path: String,
80 #[source]
82 cause: ConfigError,
83 },
84
85 #[error("invalid message: {}", string)]
87 InvalidMessage {
88 string: String,
90 #[source]
92 cause: MessageParseError,
93 },
94
95 #[error("mutex for a logged transport was poisoned")]
97 PoisonedLog,
98
99 #[error("connection reset: no ping response")]
101 PingTimeout,
102
103 #[error("unknown codec: {}", codec)]
105 UnknownCodec {
106 codec: String,
108 },
109
110 #[error("codec {} failed: {}", codec, data)]
112 CodecFailed {
113 codec: &'static str,
115 data: String,
117 },
118
119 #[error("none of the specified nicknames were usable")]
121 NoUsableNick,
122
123 #[error("stream has already been configured")]
125 StreamAlreadyConfigured,
126}
127
128#[derive(Debug, Error)]
130pub enum ConfigError {
131 #[cfg(feature = "toml_config")]
133 #[error("invalid toml")]
134 InvalidToml(#[source] TomlError),
135
136 #[cfg(feature = "json_config")]
138 #[error("invalid json")]
139 InvalidJson(#[source] serde_json::Error),
140
141 #[cfg(feature = "yaml_config")]
143 #[error("invalid yaml")]
144 InvalidYaml(#[source] serde_yaml::Error),
145
146 #[error("config format disabled: {}", format)]
148 ConfigFormatDisabled {
149 format: &'static str,
151 },
152
153 #[error("config format unknown: {}", format)]
155 UnknownConfigFormat {
156 format: String,
158 },
159
160 #[error("missing format extension")]
162 MissingExtension,
163
164 #[error("nickname not specified")]
166 NicknameNotSpecified,
167
168 #[error("server not specified")]
170 ServerNotSpecified,
171
172 #[error("could not read file {}", file)]
174 FileMissing {
175 file: String,
177 },
178}
179
180#[cfg(feature = "toml_config")]
182#[derive(Debug, Error)]
183pub enum TomlError {
184 #[error("deserialization failed")]
186 Read(#[source] toml::de::Error),
187 #[error("serialization failed")]
189 Write(#[source] toml::ser::Error),
190}
191
192impl From<ProtocolError> for Error {
193 fn from(e: ProtocolError) -> Error {
194 match e {
195 ProtocolError::Io(e) => Error::Io(e),
196 ProtocolError::InvalidMessage { string, cause } => {
197 Error::InvalidMessage { string, cause }
198 }
199 }
200 }
201}
202
203impl<T> From<SendError<T>> for Error {
204 fn from(_: SendError<T>) -> Error {
205 Error::AsyncChannelClosed
206 }
207}
208
209impl<T> From<TrySendError<T>> for Error {
210 fn from(_: TrySendError<T>) -> Error {
211 Error::AsyncChannelClosed
212 }
213}