From 5cb45bfd7eda2d59bafba38e168c8a5235d30c3d Mon Sep 17 00:00:00 2001 From: Florian Vick Date: Tue, 6 Nov 2018 21:01:03 +0100 Subject: [PATCH] Added error handling for unknown ALSA device errors (#1) Instead of taking the easy way out and killing the whole program by panicking, device enumeration and stream creation will now report the error variant 'Unknown' --- src/alsa/mod.rs | 23 ++++++++++++++++++++--- src/lib.rs | 23 +++++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/alsa/mod.rs b/src/alsa/mod.rs index 47d17bf..a32b2d6 100644 --- a/src/alsa/mod.rs +++ b/src/alsa/mod.rs @@ -92,7 +92,10 @@ impl Device { ) { -2 | -16 /* determined empirically */ => return Err(FormatsEnumerationError::DeviceNotAvailable), - e => check_errors(e).expect("device not available") + -22 => return Err(FormatsEnumerationError::InvalidArgument), + e => if check_errors(e).is_err() { + return Err(FormatsEnumerationError::Unknown) + } } let hw_params = HwParams::alloc(); @@ -271,6 +274,14 @@ impl Device { Err(FormatsEnumerationError::DeviceNotAvailable) => { return Err(DefaultFormatError::DeviceNotAvailable); }, + Err(FormatsEnumerationError::InvalidArgument) => { + // this happens sometimes when querying for input and output capabilities but + // the device supports only one + return Err(DefaultFormatError::StreamTypeNotSupported); + } + Err(FormatsEnumerationError::Unknown) => { + return Err(DefaultFormatError::DeviceNotAvailable); + } Ok(fmts) => fmts.collect(), } }; @@ -633,7 +644,10 @@ impl EventLoop { alsa::SND_PCM_NONBLOCK, ) { -16 /* determined empirically */ => return Err(CreationError::DeviceNotAvailable), - e => check_errors(e).expect("Device unavailable") + -22 => return Err(CreationError::InvalidArgument), + e => if check_errors(e).is_err() { + return Err(CreationError::Unknown); + } } let hw_params = HwParams::alloc(); @@ -693,7 +707,10 @@ impl EventLoop { alsa::SND_PCM_NONBLOCK, ) { -16 /* determined empirically */ => return Err(CreationError::DeviceNotAvailable), - e => check_errors(e).expect("Device unavailable") + -22 => return Err(CreationError::InvalidArgument), + e => if check_errors(e).is_err() { + return Err(CreationError::Unknown); + } } let hw_params = HwParams::alloc(); diff --git a/src/lib.rs b/src/lib.rs index e7f8e8b..5e4f11d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -289,6 +289,10 @@ pub enum FormatsEnumerationError { /// The device no longer exists. This can happen if the device is disconnected while the /// program is running. DeviceNotAvailable, + /// We called something the C-Layer did not understand + InvalidArgument, + /// The C-Layer returned an error we don't know about + Unknown } /// May occur when attempting to request the default input or output stream format from a `Device`. @@ -309,6 +313,11 @@ pub enum CreationError { DeviceNotAvailable, /// The required format is not supported. FormatNotSupported, + /// An ALSA device function was called with a feature it does not support + /// (trying to use capture capabilities on an output only format yields this) + InvalidArgument, + /// The C-Layer returned an error we don't know about + Unknown, } /// An iterator yielding all `Device`s currently available to the system. @@ -714,6 +723,12 @@ impl Error for FormatsEnumerationError { &FormatsEnumerationError::DeviceNotAvailable => { "The requested device is no longer available (for example, it has been unplugged)." }, + &FormatsEnumerationError::InvalidArgument => { + "Invalid argument passed to the Backend (This happens when trying to read for example capture capabilities but the device does not support it -> dmix on Linux)" + }, + &FormatsEnumerationError::Unknown => { + "An unknown error in the Backend occured" + }, } } } @@ -736,6 +751,14 @@ impl Error for CreationError { &CreationError::FormatNotSupported => { "The requested samples format is not supported by the device." }, + + &CreationError::InvalidArgument => { + "The requested device does not support this capability (invalid argument)" + } + + &CreationError::Unknown => { + "An unknown error in the Backend occured" + }, } } }