#[cfg(feature = "serenity")]
use futures::channel::mpsc::TrySendError;
pub use serde_json::Error as JsonError;
#[cfg(feature = "serenity")]
use serenity::gateway::ShardRunnerMessage;
#[cfg(feature = "gateway")]
use std::{error::Error, fmt};
#[cfg(feature = "twilight")]
use twilight_gateway::error::ChannelError;
#[cfg(feature = "gateway")]
#[derive(Debug)]
#[non_exhaustive]
pub enum JoinError {
Dropped,
NoSender,
NoCall,
TimedOut,
#[cfg(feature = "driver")]
Driver(ConnectionError),
#[cfg(feature = "serenity")]
Serenity(Box<TrySendError<ShardRunnerMessage>>),
#[cfg(feature = "twilight")]
Twilight(ChannelError),
}
#[cfg(feature = "gateway")]
impl JoinError {
pub fn should_leave_server(&self) -> bool {
matches!(self, JoinError::TimedOut)
}
#[cfg(feature = "driver")]
pub fn should_reconnect_driver(&self) -> bool {
matches!(self, JoinError::Driver(_))
}
}
#[cfg(feature = "gateway")]
impl fmt::Display for JoinError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "failed to join voice channel: ")?;
match self {
JoinError::Dropped => write!(f, "request was cancelled/dropped"),
JoinError::NoSender => write!(f, "no gateway destination"),
JoinError::NoCall => write!(f, "tried to leave a non-existent call"),
JoinError::TimedOut => write!(f, "gateway response from Discord timed out"),
#[cfg(feature = "driver")]
JoinError::Driver(_) => write!(f, "establishing connection failed"),
#[cfg(feature = "serenity")]
JoinError::Serenity(e) => e.fmt(f),
#[cfg(feature = "twilight")]
JoinError::Twilight(e) => e.fmt(f),
}
}
}
#[cfg(feature = "gateway")]
impl Error for JoinError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
JoinError::Dropped => None,
JoinError::NoSender => None,
JoinError::NoCall => None,
JoinError::TimedOut => None,
#[cfg(feature = "driver")]
JoinError::Driver(e) => Some(e),
#[cfg(feature = "serenity")]
JoinError::Serenity(e) => e.source(),
#[cfg(feature = "twilight")]
JoinError::Twilight(e) => e.source(),
}
}
}
#[cfg(all(feature = "serenity", feature = "gateway"))]
impl From<Box<TrySendError<ShardRunnerMessage>>> for JoinError {
fn from(e: Box<TrySendError<ShardRunnerMessage>>) -> Self {
JoinError::Serenity(e)
}
}
#[cfg(all(feature = "twilight", feature = "gateway"))]
impl From<ChannelError> for JoinError {
fn from(e: ChannelError) -> Self {
JoinError::Twilight(e)
}
}
#[cfg(all(feature = "driver", feature = "gateway"))]
impl From<ConnectionError> for JoinError {
fn from(e: ConnectionError) -> Self {
JoinError::Driver(e)
}
}
#[cfg(feature = "gateway")]
pub type JoinResult<T> = Result<T, JoinError>;
#[cfg(feature = "driver")]
pub use crate::{
driver::{
connection::error::{Error as ConnectionError, Result as ConnectionResult},
SchedulerError,
},
tracks::{ControlError, PlayError, TrackResult},
};