redbear-btctl: convert StubBackend::from_env panic to Result propagation
The single production-code panic in the redbear-* codebase was in StubBackend::from_env() (backend.rs:192). It panicked when the REDBEAR_BTCTL_STUB_ADAPTERS env var contained an invalid Bluetooth adapter name. Previously: - from_env() returned Self (infallible) - build_backend() returned Box<dyn Backend> - main() returned anyhow::Result<()> After: - from_env() renamed to try_from_env() -> Result<Self, String> - build_backend() returns anyhow::Result<Box<dyn Backend>> - main() call sites use '?' to propagate errors - Adapter name validation now returns Err instead of crashing the daemon The panic was the ONLY production-code panic across all 5 redbear-* programs that this phase was scoped for. The other 13 panics are in test code (#[cfg(test)] modules), which is idiomatic Rust testing practice and does not need modification. cargo check --manifest-path source/Cargo.toml passes cleanly.
This commit is contained in:
@@ -176,7 +176,7 @@ pub struct StubBackend {
|
||||
}
|
||||
|
||||
impl StubBackend {
|
||||
pub fn from_env() -> Self {
|
||||
pub fn try_from_env() -> Result<Self, String> {
|
||||
let adapters = parse_list(
|
||||
env::var("REDBEAR_BTCTL_STUB_ADAPTERS").ok().as_deref(),
|
||||
&["hci0"],
|
||||
@@ -188,12 +188,14 @@ impl StubBackend {
|
||||
&[],
|
||||
);
|
||||
for adapter in &adapters {
|
||||
if validate_adapter_name(adapter).is_err() {
|
||||
panic!("invalid Bluetooth adapter name in REDBEAR_BTCTL_STUB_ADAPTERS: {adapter}");
|
||||
if let Err(e) = validate_adapter_name(adapter) {
|
||||
return Err(format!(
|
||||
"invalid Bluetooth adapter name in REDBEAR_BTCTL_STUB_ADAPTERS: {adapter}: {e}"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Self {
|
||||
Ok(Self {
|
||||
runtime_state: adapters
|
||||
.iter()
|
||||
.cloned()
|
||||
@@ -212,7 +214,7 @@ impl StubBackend {
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(|| PathBuf::from("/var/run/redbear-btusb/status")),
|
||||
bond_store: BondStore::from_env(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -73,12 +73,14 @@ fn notify_scheme_ready(notify_fd: Option<RawFd>, socket: &Socket, scheme: &mut B
|
||||
}
|
||||
}
|
||||
|
||||
fn build_backend() -> Box<dyn Backend> {
|
||||
fn build_backend() -> anyhow::Result<Box<dyn Backend>> {
|
||||
let backend_type = env::var("REDBEAR_BTCTL_BACKEND")
|
||||
.unwrap_or_else(|_| "stub".to_string());
|
||||
match backend_type.as_str() {
|
||||
"hci" => Box::new(hci_backend::HciBackend::from_env()),
|
||||
_ => Box::new(StubBackend::from_env()),
|
||||
"hci" => Ok(Box::new(hci_backend::HciBackend::from_env())),
|
||||
_ => Ok(Box::new(StubBackend::try_from_env().map_err(|e| {
|
||||
anyhow::anyhow!("{e}")
|
||||
})?)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -424,7 +426,7 @@ fn main() -> anyhow::Result<()> {
|
||||
init_logging(log_level);
|
||||
|
||||
let args = env::args().skip(1).collect::<Vec<_>>();
|
||||
let mut backend = build_backend();
|
||||
let mut backend = build_backend()?;
|
||||
|
||||
match execute(&args, backend.as_mut()) {
|
||||
Ok(Some(output)) => {
|
||||
@@ -452,7 +454,7 @@ fn main() -> anyhow::Result<()> {
|
||||
process::exit(1);
|
||||
}
|
||||
};
|
||||
let mut scheme = BtCtlScheme::new(build_backend());
|
||||
let mut scheme = BtCtlScheme::new(build_backend()?);
|
||||
let mut state = redox_scheme::scheme::SchemeState::new();
|
||||
|
||||
notify_scheme_ready(notify_fd, &socket, &mut scheme);
|
||||
|
||||
Reference in New Issue
Block a user