Input, Driver: Make error messages more idiomatic (#74)

This commit is contained in:
Vilgot Fredenberg
2021-05-21 11:04:12 +02:00
committed by Kyle Simpson
parent 3e0793644f
commit 55e1567b90
5 changed files with 82 additions and 50 deletions

View File

@@ -127,6 +127,7 @@ features = ["v4"]
[dependencies.xsalsa20poly1305]
optional = true
version = "0.7"
features = ["std"]
[dev-dependencies]
criterion = "0.3"

View File

@@ -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.
@@ -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>;

View File

@@ -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 {

View File

@@ -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"),
}
}
}
@@ -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,
@@ -132,11 +132,11 @@ 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),
}
}
}
@@ -144,11 +144,11 @@ impl fmt::Display for DcaError {
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(),
}
}
}

View File

@@ -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"),
}
}
}