1#[cfg(feature = "skua")]
4use futures::channel::mpsc::TrySendError;
5#[cfg(not(feature = "simd-json"))]
6pub use serde_json::Error as JsonError;
7#[cfg(feature = "skua")]
8use skua::gateway::ShardRunnerMessage;
9#[cfg(feature = "simd-json")]
10pub use simd_json::Error as JsonError;
11#[cfg(feature = "gateway")]
12use std::{error::Error, fmt};
13#[cfg(feature = "twilight")]
14use twilight_gateway::error::SendError;
15
16#[cfg(feature = "gateway")]
17#[derive(Debug)]
18#[non_exhaustive]
19pub enum JoinError {
22 Dropped,
24 NoSender,
27 NoCall,
31 TimedOut,
43 #[cfg(feature = "driver")]
44 Driver(ConnectionError),
49 #[cfg(feature = "skua")]
50 Skua(Box<TrySendError<ShardRunnerMessage>>),
52 #[cfg(feature = "twilight")]
53 Twilight(SendError),
55}
56
57#[cfg(feature = "gateway")]
58impl JoinError {
59 pub fn should_leave_server(&self) -> bool {
66 matches!(self, JoinError::TimedOut)
67 }
68
69 #[cfg(feature = "driver")]
70 pub fn should_reconnect_driver(&self) -> bool {
78 matches!(self, JoinError::Driver(_))
79 }
80}
81
82#[cfg(feature = "gateway")]
83impl fmt::Display for JoinError {
84 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85 write!(f, "failed to join voice channel: ")?;
86 match self {
87 JoinError::Dropped => write!(f, "request was cancelled/dropped"),
88 JoinError::NoSender => write!(f, "no gateway destination"),
89 JoinError::NoCall => write!(f, "tried to leave a non-existent call"),
90 JoinError::TimedOut => write!(f, "gateway response from Discord timed out"),
91 #[cfg(feature = "driver")]
92 JoinError::Driver(_) => write!(f, "establishing connection failed"),
93 #[cfg(feature = "skua")]
94 JoinError::Skua(e) => e.fmt(f),
95 #[cfg(feature = "twilight")]
96 JoinError::Twilight(e) => e.fmt(f),
97 }
98 }
99}
100
101#[cfg(feature = "gateway")]
102impl Error for JoinError {
103 fn source(&self) -> Option<&(dyn Error + 'static)> {
104 match self {
105 JoinError::Dropped => None,
106 JoinError::NoSender => None,
107 JoinError::NoCall => None,
108 JoinError::TimedOut => None,
109 #[cfg(feature = "driver")]
110 JoinError::Driver(e) => Some(e),
111 #[cfg(feature = "skua")]
112 JoinError::Skua(e) => e.source(),
113 #[cfg(feature = "twilight")]
114 JoinError::Twilight(e) => e.source(),
115 }
116 }
117}
118
119#[cfg(all(feature = "skua", feature = "gateway"))]
120impl From<Box<TrySendError<ShardRunnerMessage>>> for JoinError {
121 fn from(e: Box<TrySendError<ShardRunnerMessage>>) -> Self {
122 JoinError::Skua(e)
123 }
124}
125
126#[cfg(all(feature = "twilight", feature = "gateway"))]
127impl From<SendError> for JoinError {
128 fn from(e: SendError) -> Self {
129 JoinError::Twilight(e)
130 }
131}
132
133#[cfg(all(feature = "driver", feature = "gateway"))]
134impl From<ConnectionError> for JoinError {
135 fn from(e: ConnectionError) -> Self {
136 JoinError::Driver(e)
137 }
138}
139
140#[cfg(feature = "gateway")]
141pub type JoinResult<T> = Result<T, JoinError>;
143
144#[cfg(feature = "driver")]
145pub use crate::{
146 driver::{
147 connection::error::{Error as ConnectionError, Result as ConnectionResult},
148 SchedulerError,
149 },
150 tracks::{ControlError, PlayError, TrackResult},
151};