#[cfg(any(feature = "zlib-stock", feature = "zlib-simd"))]
pub use crate::inflater::{CompressionError, CompressionErrorType};
use std::{
error::Error,
fmt::{Debug, Display, Formatter, Result as FmtResult},
};
#[derive(Debug)]
pub struct ChannelError {
pub(crate) kind: ChannelErrorType,
pub(crate) source: Option<Box<dyn Error + Send + Sync>>,
}
impl ChannelError {
#[must_use = "retrieving the type has no effect if left unused"]
pub const fn kind(&self) -> &ChannelErrorType {
&self.kind
}
#[must_use = "consuming the error and retrieving the source has no effect if left unused"]
pub fn into_source(self) -> Option<Box<dyn Error + Send + Sync>> {
self.source
}
#[must_use = "consuming the error into its parts has no effect if left unused"]
pub fn into_parts(self) -> (ChannelErrorType, Option<Box<dyn Error + Send + Sync>>) {
(self.kind, None)
}
}
impl Display for ChannelError {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match self.kind {
ChannelErrorType::Closed => f.write_str("tried sending over a closed channel"),
}
}
}
impl Error for ChannelError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
self.source
.as_ref()
.map(|source| &**source as &(dyn Error + 'static))
}
}
#[derive(Debug)]
#[non_exhaustive]
pub enum ChannelErrorType {
Closed,
}
#[cfg(feature = "twilight-http")]
#[derive(Debug)]
pub struct StartRecommendedError {
pub(crate) kind: StartRecommendedErrorType,
pub(crate) source: Option<Box<dyn Error + Send + Sync>>,
}
#[cfg(feature = "twilight-http")]
impl StartRecommendedError {
#[must_use = "retrieving the type has no effect if left unused"]
pub const fn kind(&self) -> &StartRecommendedErrorType {
&self.kind
}
#[must_use = "consuming the error and retrieving the source has no effect if left unused"]
pub fn into_source(self) -> Option<Box<dyn Error + Send + Sync>> {
self.source
}
#[must_use = "consuming the error into its parts has no effect if left unused"]
pub fn into_parts(
self,
) -> (
StartRecommendedErrorType,
Option<Box<dyn Error + Send + Sync>>,
) {
(self.kind, None)
}
}
#[cfg(feature = "twilight-http")]
impl Display for StartRecommendedError {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match self.kind {
StartRecommendedErrorType::Deserializing => {
f.write_str("payload isn't a recognized type")
}
StartRecommendedErrorType::Request => f.write_str("request failed to complete"),
}
}
}
#[cfg(feature = "twilight-http")]
impl Error for StartRecommendedError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
self.source
.as_ref()
.map(|source| &**source as &(dyn Error + 'static))
}
}
#[cfg(feature = "twilight-http")]
#[derive(Debug)]
pub enum StartRecommendedErrorType {
Deserializing,
Request,
}
#[derive(Debug)]
pub struct ReceiveMessageError {
pub(crate) kind: ReceiveMessageErrorType,
pub(crate) source: Option<Box<dyn Error + Send + Sync>>,
}
impl ReceiveMessageError {
#[must_use = "retrieving the type has no effect if left unused"]
pub const fn kind(&self) -> &ReceiveMessageErrorType {
&self.kind
}
#[must_use = "consuming the error and retrieving the source has no effect if left unused"]
pub fn into_source(self) -> Option<Box<dyn Error + Send + Sync>> {
self.source
}
#[must_use = "consuming the error into its parts has no effect if left unused"]
pub fn into_parts(
self,
) -> (
ReceiveMessageErrorType,
Option<Box<dyn Error + Send + Sync>>,
) {
(self.kind, None)
}
#[cfg(any(feature = "zlib-stock", feature = "zlib-simd"))]
pub(crate) fn from_compression(source: CompressionError) -> Self {
Self {
kind: ReceiveMessageErrorType::Compression,
source: Some(Box::new(source)),
}
}
pub(crate) fn from_websocket(source: tokio_websockets::Error) -> Self {
Self {
kind: ReceiveMessageErrorType::WebSocket,
source: Some(Box::new(source)),
}
}
}
impl Display for ReceiveMessageError {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match &self.kind {
#[cfg(any(feature = "zlib-stock", feature = "zlib-simd"))]
ReceiveMessageErrorType::Compression => {
f.write_str("binary message could not be decompressed")
}
ReceiveMessageErrorType::Deserializing { event } => {
f.write_str("gateway event could not be deserialized: event=")?;
f.write_str(event)
}
ReceiveMessageErrorType::Reconnect => f.write_str("failed to reconnect to the gateway"),
ReceiveMessageErrorType::WebSocket => f.write_str("websocket connection error"),
}
}
}
impl Error for ReceiveMessageError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
self.source
.as_ref()
.map(|source| &**source as &(dyn Error + 'static))
}
}
#[derive(Debug)]
#[non_exhaustive]
pub enum ReceiveMessageErrorType {
#[cfg(any(feature = "zlib-stock", feature = "zlib-simd"))]
Compression,
Deserializing {
event: String,
},
Reconnect,
WebSocket,
}
#[cfg(test)]
mod tests {
use super::{ReceiveMessageError, ReceiveMessageErrorType};
use static_assertions::assert_impl_all;
use std::{error::Error, fmt::Debug};
assert_impl_all!(ReceiveMessageErrorType: Debug, Send, Sync);
assert_impl_all!(ReceiveMessageError: Error, Send, Sync);
#[test]
fn receive_message_error_display() {
let messages: [(ReceiveMessageErrorType, &str); 4] = [
(
ReceiveMessageErrorType::Compression,
"binary message could not be decompressed",
),
(
ReceiveMessageErrorType::Deserializing {
event: r#"{"t":null,"s":null,"op":10,"d":{"heartbeat_interval":41250,"_trace":["[\"gateway-prd-us-east1-b-0568\",{\"micros\":0.0}]"]}}"#.to_owned(),
},
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}]"]}}"#,
),
(
ReceiveMessageErrorType::Reconnect,
"failed to reconnect to the gateway",
),
(ReceiveMessageErrorType::WebSocket, "websocket connection error"),
];
for (kind, message) in messages {
let error = ReceiveMessageError { kind, source: None };
assert_eq!(error.to_string(), message);
}
}
}