twilight_gateway/
error.rs1#[cfg(any(feature = "zlib", feature = "zstd"))]
4pub use crate::compression::{CompressionError, CompressionErrorType};
5
6use std::{
7 error::Error,
8 fmt::{Debug, Display, Formatter, Result as FmtResult},
9};
10
11#[derive(Debug)]
13pub struct ChannelError {
14 pub(crate) kind: ChannelErrorType,
16 pub(crate) source: Option<Box<dyn Error + Send + Sync>>,
18}
19
20impl ChannelError {
21 #[must_use = "retrieving the type has no effect if left unused"]
23 pub const fn kind(&self) -> &ChannelErrorType {
24 &self.kind
25 }
26
27 #[must_use = "consuming the error and retrieving the source has no effect if left unused"]
29 pub fn into_source(self) -> Option<Box<dyn Error + Send + Sync>> {
30 self.source
31 }
32
33 #[must_use = "consuming the error into its parts has no effect if left unused"]
35 pub fn into_parts(self) -> (ChannelErrorType, Option<Box<dyn Error + Send + Sync>>) {
36 (self.kind, None)
37 }
38}
39
40impl Display for ChannelError {
41 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
42 match self.kind {
43 ChannelErrorType::Closed => f.write_str("tried sending over a closed channel"),
44 }
45 }
46}
47
48impl Error for ChannelError {
49 fn source(&self) -> Option<&(dyn Error + 'static)> {
50 self.source
51 .as_ref()
52 .map(|source| &**source as &(dyn Error + 'static))
53 }
54}
55
56#[derive(Debug)]
58#[non_exhaustive]
59pub enum ChannelErrorType {
60 Closed,
62}
63
64#[cfg(feature = "twilight-http")]
67#[deprecated(since = "0.17.2")]
68#[derive(Debug)]
69pub struct StartRecommendedError {
70 #[allow(deprecated)]
72 pub(crate) kind: StartRecommendedErrorType,
73 pub(crate) source: Option<Box<dyn Error + Send + Sync>>,
75}
76
77#[allow(deprecated)]
78#[cfg(feature = "twilight-http")]
79impl StartRecommendedError {
80 #[must_use = "retrieving the type has no effect if left unused"]
82 pub const fn kind(&self) -> &StartRecommendedErrorType {
83 &self.kind
84 }
85
86 #[must_use = "consuming the error and retrieving the source has no effect if left unused"]
88 pub fn into_source(self) -> Option<Box<dyn Error + Send + Sync>> {
89 self.source
90 }
91
92 #[must_use = "consuming the error into its parts has no effect if left unused"]
94 pub fn into_parts(
95 self,
96 ) -> (
97 StartRecommendedErrorType,
98 Option<Box<dyn Error + Send + Sync>>,
99 ) {
100 (self.kind, None)
101 }
102}
103
104#[allow(deprecated)]
105#[cfg(feature = "twilight-http")]
106impl Display for StartRecommendedError {
107 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
108 match self.kind {
109 StartRecommendedErrorType::Deserializing => {
110 f.write_str("payload isn't a recognized type")
111 }
112 StartRecommendedErrorType::Request => f.write_str("request failed to complete"),
113 }
114 }
115}
116
117#[allow(deprecated)]
118#[cfg(feature = "twilight-http")]
119impl Error for StartRecommendedError {
120 fn source(&self) -> Option<&(dyn Error + 'static)> {
121 self.source
122 .as_ref()
123 .map(|source| &**source as &(dyn Error + 'static))
124 }
125}
126
127#[cfg(feature = "twilight-http")]
129#[deprecated(since = "0.17.2")]
130#[derive(Debug)]
131pub enum StartRecommendedErrorType {
132 Deserializing,
137 Request,
141}
142
143#[derive(Debug)]
145pub struct ReceiveMessageError {
146 pub(crate) kind: ReceiveMessageErrorType,
148 pub(crate) source: Option<Box<dyn Error + Send + Sync>>,
150}
151
152impl ReceiveMessageError {
153 #[must_use = "retrieving the type has no effect if left unused"]
155 pub const fn kind(&self) -> &ReceiveMessageErrorType {
156 &self.kind
157 }
158
159 #[must_use = "consuming the error and retrieving the source has no effect if left unused"]
161 pub fn into_source(self) -> Option<Box<dyn Error + Send + Sync>> {
162 self.source
163 }
164
165 #[must_use = "consuming the error into its parts has no effect if left unused"]
167 pub fn into_parts(
168 self,
169 ) -> (
170 ReceiveMessageErrorType,
171 Option<Box<dyn Error + Send + Sync>>,
172 ) {
173 (self.kind, None)
174 }
175
176 #[cfg(any(feature = "zlib", feature = "zstd"))]
178 pub(crate) fn from_compression(source: CompressionError) -> Self {
179 Self {
180 kind: ReceiveMessageErrorType::Compression,
181 source: Some(Box::new(source)),
182 }
183 }
184}
185
186impl Display for ReceiveMessageError {
187 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
188 match &self.kind {
189 #[cfg(any(feature = "zlib", feature = "zstd"))]
190 ReceiveMessageErrorType::Compression => {
191 f.write_str("binary message could not be decompressed")
192 }
193 ReceiveMessageErrorType::Deserializing { event } => {
194 f.write_str("gateway event could not be deserialized: event=")?;
195 f.write_str(event)
196 }
197 ReceiveMessageErrorType::Reconnect => f.write_str("failed to reconnect to the gateway"),
198 }
199 }
200}
201
202impl Error for ReceiveMessageError {
203 fn source(&self) -> Option<&(dyn Error + 'static)> {
204 self.source
205 .as_ref()
206 .map(|source| &**source as &(dyn Error + 'static))
207 }
208}
209
210#[derive(Debug)]
212#[non_exhaustive]
213pub enum ReceiveMessageErrorType {
214 #[cfg(any(feature = "zlib", feature = "zstd"))]
218 Compression,
219 Deserializing {
221 event: String,
225 },
226 Reconnect,
228}
229
230#[cfg(test)]
231mod tests {
232 use super::{ReceiveMessageError, ReceiveMessageErrorType};
233 use static_assertions::assert_impl_all;
234 use std::{error::Error, fmt::Debug};
235
236 assert_impl_all!(ReceiveMessageErrorType: Debug, Send, Sync);
237 assert_impl_all!(ReceiveMessageError: Error, Send, Sync);
238
239 #[test]
240 fn receive_message_error_display() {
241 let messages: [(ReceiveMessageErrorType, &str); 3] = [
242 (
243 ReceiveMessageErrorType::Compression,
244 "binary message could not be decompressed",
245 ),
246 (
247 ReceiveMessageErrorType::Deserializing {
248 event: r#"{"t":null,"s":null,"op":10,"d":{"heartbeat_interval":41250,"_trace":["[\"gateway-prd-us-east1-b-0568\",{\"micros\":0.0}]"]}}"#.to_owned(),
249 },
250 r#"gateway event could not be deserialized: event={"t":null,"s":null,"op":10,"d":{"heartbeat_interval":41250,"_trace":["[\"gateway-prd-us-east1-b-0568\",{\"micros\":0.0}]"]}}"#,
251 ),
252 (
253 ReceiveMessageErrorType::Reconnect,
254 "failed to reconnect to the gateway",
255 ),
256 ];
257
258 for (kind, message) in messages {
259 let error = ReceiveMessageError { kind, source: None };
260
261 assert_eq!(error.to_string(), message);
262 }
263 }
264}