Skip to content

Commit

Permalink
Input, Driver: Make error messages more idiomatic (#74)
Browse files Browse the repository at this point in the history
  • Loading branch information
vilgotf authored and FelixMcFelix committed May 21, 2021
1 parent 8000da6 commit a96f033
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 50 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ features = ["v4"]
[dependencies.xsalsa20poly1305]
optional = true
version = "0.7"
features = ["std"]

[dev-dependencies]
criterion = "0.3"
Expand Down
48 changes: 32 additions & 16 deletions src/driver/connection/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
};
use flume::SendError;
use serde_json::Error as JsonError;
use std::{error::Error as ErrorTrait, fmt, io::Error as IoError};
use std::{error::Error as StdError, fmt, io::Error as IoError};
use xsalsa20poly1305::aead::Error as CryptoError;

/// Errors encountered while connecting to a Discord voice server over the driver.
Expand Down Expand Up @@ -84,27 +84,43 @@ impl From<WsError> for Error {

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Failed to connect to Discord RTP server: ")?;
write!(f, "failed to connect to Discord RTP server: ")?;
use Error::*;
match self {
AttemptDiscarded => write!(f, "connection attempt was aborted/discarded."),
Crypto(c) => write!(f, "cryptography error {}.", c),
CryptoModeInvalid => write!(f, "server changed negotiated encryption mode."),
CryptoModeUnavailable => write!(f, "server did not offer chosen encryption mode."),
EndpointUrl => write!(f, "endpoint URL received from gateway was invalid."),
ExpectedHandshake => write!(f, "voice initialisation protocol was violated."),
IllegalDiscoveryResponse =>
write!(f, "IP discovery/NAT punching response was invalid."),
IllegalIp => write!(f, "IP discovery/NAT punching response had bad IP value."),
Io(i) => write!(f, "I/O failure ({}).", i),
Json(j) => write!(f, "JSON (de)serialization issue ({}).", j),
InterconnectFailure(r) => write!(f, "failed to contact other task ({:?})", r),
Ws(w) => write!(f, "websocket issue ({:?}).", w),
AttemptDiscarded => write!(f, "connection attempt was aborted/discarded"),
Crypto(e) => e.fmt(f),
CryptoModeInvalid => write!(f, "server changed negotiated encryption mode"),
CryptoModeUnavailable => write!(f, "server did not offer chosen encryption mode"),
EndpointUrl => write!(f, "endpoint URL received from gateway was invalid"),
ExpectedHandshake => write!(f, "voice initialisation protocol was violated"),
IllegalDiscoveryResponse => write!(f, "IP discovery/NAT punching response was invalid"),
IllegalIp => write!(f, "IP discovery/NAT punching response had bad IP value"),
Io(e) => e.fmt(f),
Json(e) => e.fmt(f),
InterconnectFailure(e) => write!(f, "failed to contact other task ({:?})", e),
Ws(e) => write!(f, "websocket issue ({:?}).", e),
}
}
}

impl ErrorTrait for Error {}
impl StdError for Error {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
match self {
Error::AttemptDiscarded => None,
Error::Crypto(e) => e.source(),
Error::CryptoModeInvalid => None,
Error::CryptoModeUnavailable => None,
Error::EndpointUrl => None,
Error::ExpectedHandshake => None,
Error::IllegalDiscoveryResponse => None,
Error::IllegalIp => None,
Error::Io(e) => e.source(),
Error::Json(e) => e.source(),
Error::InterconnectFailure(_) => None,
Error::Ws(_) => None,
}
}
}

/// Convenience type for Discord voice/driver connection error handling.
pub type Result<T> = std::result::Result<T, Error>;
33 changes: 24 additions & 9 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,24 +78,39 @@ impl JoinError {
#[cfg(feature = "gateway-core")]
impl fmt::Display for JoinError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Failed to Join Voice channel: ")?;
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."),
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-core")]
JoinError::Driver(t) => write!(f, "internal driver error {}.", t),
JoinError::Driver(_) => write!(f, "establishing connection failed"),
#[cfg(feature = "serenity")]
JoinError::Serenity(t) => write!(f, "serenity failure {}.", t),
JoinError::Serenity(e) => e.fmt(f),
#[cfg(feature = "twilight")]
JoinError::Twilight(t) => write!(f, "twilight failure {}.", t),
JoinError::Twilight(e) => e.fmt(f),
}
}
}

#[cfg(feature = "gateway-core")]
impl Error for JoinError {}
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-core")]
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-core"))]
impl From<TrySendError<InterMessage>> for JoinError {
Expand Down
42 changes: 21 additions & 21 deletions src/input/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,20 +72,20 @@ impl From<OpusError> for Error {
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::Dca(e) => write!(f, "{}", e),
Error::Io(e) => write!(f, "{}", e),
Error::Dca(_) => write!(f, "opening file DCA failed"),
Error::Io(e) => e.fmt(f),
Error::Json {
error,
error: _,
parsed_text: _,
} => write!(f, "{}", error),
Error::Opus(e) => write!(f, "{}", e),
Error::Metadata => write!(f, "Failed to extract metadata"),
Error::Stdout => write!(f, "Failed to create stdout"),
Error::Streams => write!(f, "Error while checking if path is stereo"),
Error::Streamcatcher(e) => write!(f, "{}", e),
Error::YouTubeDlProcessing(_) => write!(f, "Processing JSON from youtube-dl failed"),
Error::YouTubeDlRun(_) => write!(f, "youtube-dl encountered an error"),
Error::YouTubeDlUrl(_) => write!(f, "Missing url field in JSON"),
} => write!(f, "parsing JSON failed"),
Error::Opus(e) => e.fmt(f),
Error::Metadata => write!(f, "extracting metadata failed"),
Error::Stdout => write!(f, "creating stdout failed"),
Error::Streams => write!(f, "checking if path is stereo failed"),
Error::Streamcatcher(_) => write!(f, "invalid config for cached input"),
Error::YouTubeDlProcessing(_) => write!(f, "youtube-dl returned invalid JSON"),
Error::YouTubeDlRun(o) => write!(f, "youtube-dl encontered an error: {:?}", o),
Error::YouTubeDlUrl(_) => write!(f, "missing youtube-dl url"),
}
}
}
Expand All @@ -94,12 +94,12 @@ impl StdError for Error {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
match self {
Error::Dca(e) => Some(e),
Error::Io(e) => Some(e),
Error::Io(e) => e.source(),
Error::Json {
error,
parsed_text: _,
} => Some(error),
Error::Opus(e) => Some(e),
Error::Opus(e) => e.source(),
Error::Metadata => None,
Error::Stdout => None,
Error::Streams => None,
Expand Down Expand Up @@ -132,23 +132,23 @@ pub enum DcaError {
impl fmt::Display for DcaError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
DcaError::IoError(e) => write!(f, "{}", e),
DcaError::InvalidHeader => write!(f, "Invalid DCA JSON header"),
DcaError::InvalidMetadata(e) => write!(f, "{}", e),
DcaError::InvalidSize(e) => write!(f, "Invalid metadata block size: {}", e),
DcaError::Opus(e) => write!(f, "{}", e),
DcaError::IoError(e) => e.fmt(f),
DcaError::InvalidHeader => write!(f, "invalid header"),
DcaError::InvalidMetadata(_) => write!(f, "invalid metadata"),
DcaError::InvalidSize(e) => write!(f, "invalid metadata block size: {}", e),
DcaError::Opus(e) => e.fmt(f),
}
}
}

impl StdError for DcaError {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
match self {
DcaError::IoError(e) => Some(e),
DcaError::IoError(e) => e.source(),
DcaError::InvalidHeader => None,
DcaError::InvalidMetadata(e) => Some(e),
DcaError::InvalidSize(_) => None,
DcaError::Opus(e) => Some(e),
DcaError::Opus(e) => e.source(),
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/tracks/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ pub enum TrackError {

impl fmt::Display for TrackError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Failed to operate on track (handle): ")?;
write!(f, "failed to operate on track (handle): ")?;
match self {
TrackError::Finished => write!(f, "track ended."),
TrackError::Finished => write!(f, "track ended"),
TrackError::InvalidTrackEvent =>
write!(f, "given event listener can't be fired on a track."),
TrackError::SeekUnsupported => write!(f, "track did not support seeking."),
write!(f, "given event listener can't be fired on a track"),
TrackError::SeekUnsupported => write!(f, "track did not support seeking"),
}
}
}
Expand Down

0 comments on commit a96f033

Please sign in to comment.