Switch to dtolnay's `thiserror` for handling error boilerplate
Currently CPAL only really uses `failure` for its `derive` capabilities and the ability to easily generate implementations for `Display`. That said there are a few issues with using the `failure` crate: - `failure` does not provie a `std::error::Error` implementation without first converting error types into `failure::Error`. - It leaks significantly into the public API and expects downstream users to also depend on `failure` and the non-std `Fail` trait for their own error handling. - Solved problems such as downcasting of causal errors which have since been addressed in `std`. - Provides application-friendly `Fail` trait and `failure::Error` type, not particularly useful to libraries like CPAL. The [`thiserror` crate](https://github.com/dtolnay/thiserror) is better targeted towards libraries, does not leak into the public API while providing easy generation of `Display`, `From` and `std::error::Error` implementations including proper handling of the newish `std::error::Error::source` method.
This commit is contained in:
parent
be54ffff09
commit
d9d4a906c9
|
@ -12,7 +12,7 @@ keywords = ["audio", "sound"]
|
|||
asio = ["asio-sys"] # Only available on Windows. See README for setup instructions.
|
||||
|
||||
[dependencies]
|
||||
failure = "0.1.5"
|
||||
thiserror = "1.0.2"
|
||||
lazy_static = "1.3"
|
||||
num-traits = "0.2.6"
|
||||
|
||||
|
|
138
src/error.rs
138
src/error.rs
|
@ -1,8 +1,8 @@
|
|||
use failure::Fail;
|
||||
use thiserror::Error;
|
||||
|
||||
/// The requested host, although supported on this platform, is unavailable.
|
||||
#[derive(Clone, Debug, Fail)]
|
||||
#[fail(display = "the requested host is unavailable")]
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[error("the requested host is unavailable")]
|
||||
pub struct HostUnavailable;
|
||||
|
||||
/// Some error has occurred that is specific to the backend from which it was produced.
|
||||
|
@ -17,101 +17,95 @@ pub struct HostUnavailable;
|
|||
/// **Note:** If you notice a `BackendSpecificError` that you believe could be better handled in a
|
||||
/// cross-platform manner, please create an issue or submit a pull request with a patch that adds
|
||||
/// the necessary error variant to the appropriate error enum.
|
||||
#[derive(Clone, Debug, Fail)]
|
||||
#[fail(display = "A backend-specific error has occurred: {}", description)]
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[error("A backend-specific error has occurred: {description}")]
|
||||
pub struct BackendSpecificError {
|
||||
pub description: String,
|
||||
}
|
||||
|
||||
/// An error that might occur while attempting to enumerate the available devices on a system.
|
||||
#[derive(Debug, Fail)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum DevicesError {
|
||||
/// See the `BackendSpecificError` docs for more information about this error variant.
|
||||
#[fail(display = "{}", err)]
|
||||
#[error("{err}")]
|
||||
BackendSpecific {
|
||||
#[fail(cause)]
|
||||
#[from]
|
||||
err: BackendSpecificError,
|
||||
},
|
||||
}
|
||||
|
||||
/// An error that may occur while attempting to retrieve a device name.
|
||||
#[derive(Debug, Fail)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum DeviceNameError {
|
||||
/// See the `BackendSpecificError` docs for more information about this error variant.
|
||||
#[fail(display = "{}", err)]
|
||||
#[error("{err}")]
|
||||
BackendSpecific {
|
||||
#[fail(cause)]
|
||||
#[from]
|
||||
err: BackendSpecificError,
|
||||
},
|
||||
}
|
||||
|
||||
/// Error that can happen when enumerating the list of supported formats.
|
||||
#[derive(Debug, Fail)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SupportedFormatsError {
|
||||
/// The device no longer exists. This can happen if the device is disconnected while the
|
||||
/// program is running.
|
||||
#[fail(
|
||||
display = "The requested device is no longer available. For example, it has been unplugged."
|
||||
)]
|
||||
#[error("The requested device is no longer available. For example, it has been unplugged.")]
|
||||
DeviceNotAvailable,
|
||||
/// We called something the C-Layer did not understand
|
||||
#[fail(
|
||||
display = "Invalid argument passed to the backend. For example, this happens when trying to read capture capabilities when the device does not support it."
|
||||
#[error(
|
||||
"Invalid argument passed to the backend. For example, this happens when trying to read capture capabilities when the device does not support it."
|
||||
)]
|
||||
InvalidArgument,
|
||||
/// See the `BackendSpecificError` docs for more information about this error variant.
|
||||
#[fail(display = "{}", err)]
|
||||
#[error("{err}")]
|
||||
BackendSpecific {
|
||||
#[fail(cause)]
|
||||
#[from]
|
||||
err: BackendSpecificError,
|
||||
},
|
||||
}
|
||||
|
||||
/// May occur when attempting to request the default input or output stream format from a `Device`.
|
||||
#[derive(Debug, Fail)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum DefaultFormatError {
|
||||
/// The device no longer exists. This can happen if the device is disconnected while the
|
||||
/// program is running.
|
||||
#[fail(
|
||||
display = "The requested device is no longer available. For example, it has been unplugged."
|
||||
)]
|
||||
#[error("The requested device is no longer available. For example, it has been unplugged.")]
|
||||
DeviceNotAvailable,
|
||||
/// Returned if e.g. the default input format was requested on an output-only audio device.
|
||||
#[fail(display = "The requested stream type is not supported by the device.")]
|
||||
#[error("The requested stream type is not supported by the device.")]
|
||||
StreamTypeNotSupported,
|
||||
/// See the `BackendSpecificError` docs for more information about this error variant.
|
||||
#[fail(display = "{}", err)]
|
||||
#[error("{err}")]
|
||||
BackendSpecific {
|
||||
#[fail(cause)]
|
||||
#[from]
|
||||
err: BackendSpecificError,
|
||||
},
|
||||
}
|
||||
|
||||
/// Error that can happen when creating a `Stream`.
|
||||
#[derive(Debug, Fail)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum BuildStreamError {
|
||||
/// The device no longer exists. This can happen if the device is disconnected while the
|
||||
/// program is running.
|
||||
#[fail(
|
||||
display = "The requested device is no longer available. For example, it has been unplugged."
|
||||
)]
|
||||
#[error("The requested device is no longer available. For example, it has been unplugged.")]
|
||||
DeviceNotAvailable,
|
||||
/// The required format is not supported.
|
||||
#[fail(display = "The requested stream format is not supported by the device.")]
|
||||
#[error("The requested stream format is not supported by the device.")]
|
||||
FormatNotSupported,
|
||||
/// We called something the C-Layer did not understand
|
||||
///
|
||||
/// On ALSA device functions called with a feature they do not support will yield this. E.g.
|
||||
/// Trying to use capture capabilities on an output only format yields this.
|
||||
#[fail(display = "The requested device does not support this capability (invalid argument)")]
|
||||
#[error("The requested device does not support this capability (invalid argument)")]
|
||||
InvalidArgument,
|
||||
/// Occurs if adding a new Stream ID would cause an integer overflow.
|
||||
#[fail(display = "Adding a new stream ID would cause an overflow")]
|
||||
#[error("Adding a new stream ID would cause an overflow")]
|
||||
StreamIdOverflow,
|
||||
/// See the `BackendSpecificError` docs for more information about this error variant.
|
||||
#[fail(display = "{}", err)]
|
||||
#[error("{err}")]
|
||||
BackendSpecific {
|
||||
#[fail(cause)]
|
||||
#[from]
|
||||
err: BackendSpecificError,
|
||||
},
|
||||
}
|
||||
|
@ -121,15 +115,15 @@ pub enum BuildStreamError {
|
|||
/// As of writing this, only macOS may immediately return an error while calling this method. This
|
||||
/// is because both the alsa and wasapi backends only enqueue these commands and do not process
|
||||
/// them immediately.
|
||||
#[derive(Debug, Fail)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum PlayStreamError {
|
||||
/// The device associated with the stream is no longer available.
|
||||
#[fail(display = "the device associated with the stream is no longer available")]
|
||||
#[error("the device associated with the stream is no longer available")]
|
||||
DeviceNotAvailable,
|
||||
/// See the `BackendSpecificError` docs for more information about this error variant.
|
||||
#[fail(display = "{}", err)]
|
||||
#[error("{err}")]
|
||||
BackendSpecific {
|
||||
#[fail(cause)]
|
||||
#[from]
|
||||
err: BackendSpecificError,
|
||||
},
|
||||
}
|
||||
|
@ -139,80 +133,30 @@ pub enum PlayStreamError {
|
|||
/// As of writing this, only macOS may immediately return an error while calling this method. This
|
||||
/// is because both the alsa and wasapi backends only enqueue these commands and do not process
|
||||
/// them immediately.
|
||||
#[derive(Debug, Fail)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum PauseStreamError {
|
||||
/// The device associated with the stream is no longer available.
|
||||
#[fail(display = "the device associated with the stream is no longer available")]
|
||||
#[error("the device associated with the stream is no longer available")]
|
||||
DeviceNotAvailable,
|
||||
/// See the `BackendSpecificError` docs for more information about this error variant.
|
||||
#[fail(display = "{}", err)]
|
||||
#[error("{err}")]
|
||||
BackendSpecific {
|
||||
#[fail(cause)]
|
||||
#[from]
|
||||
err: BackendSpecificError,
|
||||
},
|
||||
}
|
||||
|
||||
/// Errors that might occur while a stream is running.
|
||||
#[derive(Debug, Fail)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum StreamError {
|
||||
/// The device no longer exists. This can happen if the device is disconnected while the
|
||||
/// program is running.
|
||||
#[fail(
|
||||
display = "The requested device is no longer available. For example, it has been unplugged."
|
||||
)]
|
||||
#[error("The requested device is no longer available. For example, it has been unplugged.")]
|
||||
DeviceNotAvailable,
|
||||
/// See the `BackendSpecificError` docs for more information about this error variant.
|
||||
#[fail(display = "{}", err)]
|
||||
#[error("{err}")]
|
||||
BackendSpecific {
|
||||
#[fail(cause)]
|
||||
#[from]
|
||||
err: BackendSpecificError,
|
||||
},
|
||||
}
|
||||
|
||||
impl From<BackendSpecificError> for DevicesError {
|
||||
fn from(err: BackendSpecificError) -> Self {
|
||||
DevicesError::BackendSpecific { err }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BackendSpecificError> for DeviceNameError {
|
||||
fn from(err: BackendSpecificError) -> Self {
|
||||
DeviceNameError::BackendSpecific { err }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BackendSpecificError> for SupportedFormatsError {
|
||||
fn from(err: BackendSpecificError) -> Self {
|
||||
SupportedFormatsError::BackendSpecific { err }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BackendSpecificError> for DefaultFormatError {
|
||||
fn from(err: BackendSpecificError) -> Self {
|
||||
DefaultFormatError::BackendSpecific { err }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BackendSpecificError> for BuildStreamError {
|
||||
fn from(err: BackendSpecificError) -> Self {
|
||||
BuildStreamError::BackendSpecific { err }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BackendSpecificError> for PlayStreamError {
|
||||
fn from(err: BackendSpecificError) -> Self {
|
||||
PlayStreamError::BackendSpecific { err }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BackendSpecificError> for PauseStreamError {
|
||||
fn from(err: BackendSpecificError) -> Self {
|
||||
PauseStreamError::BackendSpecific { err }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BackendSpecificError> for StreamError {
|
||||
fn from(err: BackendSpecificError) -> Self {
|
||||
StreamError::BackendSpecific { err }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -140,7 +140,6 @@
|
|||
|
||||
#![recursion_limit = "512"]
|
||||
|
||||
extern crate failure;
|
||||
#[cfg(target_os = "windows")]
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
@ -148,6 +147,7 @@ extern crate lazy_static;
|
|||
#[cfg(target_os = "emscripten")]
|
||||
#[macro_use]
|
||||
extern crate stdweb;
|
||||
extern crate thiserror;
|
||||
|
||||
pub use error::*;
|
||||
pub use platform::{
|
||||
|
|
Loading…
Reference in New Issue