From ac7ffd87d8271ae23c45ec317b133ef11494cbd3 Mon Sep 17 00:00:00 2001 From: Arnold Loubriat Date: Tue, 7 Jul 2026 22:31:08 +0200 Subject: [PATCH] fix: Don't panic on recoverable D-Bus errors on Unix --- platforms/unix/src/atspi/bus.rs | 24 ++++++++++++++---------- platforms/unix/src/context.rs | 11 ++++++++--- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/platforms/unix/src/atspi/bus.rs b/platforms/unix/src/atspi/bus.rs index 23095a62..7d533303 100644 --- a/platforms/unix/src/atspi/bus.rs +++ b/platforms/unix/src/atspi/bus.rs @@ -18,7 +18,6 @@ use atspi::{ }; use std::{ env::var, - io, sync::{Arc, OnceLock}, }; use zbus::{ @@ -172,7 +171,7 @@ impl Bus { where T: zbus::object_server::Interface, { - map_or_ignoring_broken_pipe( + map_or_ignoring_recoverable_error( self.conn.object_server().at(path, interface).await, false, |result| result, @@ -223,7 +222,7 @@ impl Bus { where T: zbus::object_server::Interface, { - map_or_ignoring_broken_pipe( + map_or_ignoring_recoverable_error( self.conn.object_server().remove::(path).await, false, |result| result, @@ -415,7 +414,7 @@ impl Bus { where B: serde::Serialize + zbus::zvariant::DynamicType, { - map_or_ignoring_broken_pipe( + map_or_ignoring_recoverable_error( self.conn .emit_signal( Option::::None, @@ -437,7 +436,7 @@ impl Bus { signal_name: &str, body: EventBodyBorrowed<'_>, ) -> Result<()> { - map_or_ignoring_broken_pipe( + map_or_ignoring_recoverable_error( self.conn .emit_signal( Option::::None, @@ -453,7 +452,14 @@ impl Bus { } } -pub(crate) fn map_or_ignoring_broken_pipe( +pub(crate) fn zbus_error_is_unrecoverable(error: &zbus::Error) -> bool { + matches!( + error, + zbus::Error::InterfaceExists(..) | zbus::Error::MissingParameter(..) + ) +} + +pub(crate) fn map_or_ignoring_recoverable_error( result: zbus::Result, default: U, f: F, @@ -463,9 +469,7 @@ where { match result { Ok(result) => Ok(f(result)), - Err(zbus::Error::InputOutput(error)) if error.kind() == io::ErrorKind::BrokenPipe => { - Ok(default) - } - Err(error) => Err(error), + Err(error) if zbus_error_is_unrecoverable(&error) => Err(error), + Err(_) => Ok(default), } } diff --git a/platforms/unix/src/context.rs b/platforms/unix/src/context.rs index 5720532b..5a990886 100644 --- a/platforms/unix/src/context.rs +++ b/platforms/unix/src/context.rs @@ -25,7 +25,7 @@ use zbus::{Connection, connection::Builder, proxy::PropertyChanged}; use crate::{ adapter::{AdapterState, Callback, Message}, - atspi::{Bus, map_or_ignoring_broken_pipe}, + atspi::{Bus, map_or_ignoring_recoverable_error, zbus_error_is_unrecoverable}, executor::Executor, util::block_on, }; @@ -58,7 +58,11 @@ pub(crate) fn get_or_init_messages() -> Sender { if let Ok(session_bus) = Builder::session() { if let Ok(session_bus) = session_bus.internal_executor(false).build().await { - run_event_loop(&executor, session_bus, rx).await.unwrap(); + if let Err(error) = run_event_loop(&executor, session_bus, rx).await { + if zbus_error_is_unrecoverable(&error) { + panic!("Accessibility event loop failed: {error}"); + } + } } } })) @@ -145,7 +149,7 @@ async fn bus_after_status_change( None => false, }; if enabled { - map_or_ignoring_broken_pipe(Bus::new(session_bus, executor).await, None, Some) + map_or_ignoring_recoverable_error(Bus::new(session_bus, executor).await, None, Some) } else { Ok(None) } @@ -195,6 +199,7 @@ async fn run_event_loop( change = changes.next() => { atspi_bus = bus_after_status_change(change, &session_bus, executor).await?; sync_adapters(&mut adapters, &atspi_bus); + } message = messages.next() => { if let Some(message) = message {