fix(event_loop): walk error source chain for BrokenPipe in OtherError
Some checks failed
CI / build + test (push) Has been cancelled
CI / cargo audit (push) Has been cancelled

The previous fix checked downcast_ref::<io::Error> directly on the
OtherError payload, but wayland-client wraps the io::Error inside
WaylandError::Io — one level deeper. Downcast failed, is_closed
stayed false, and the panic arm fired anyway.

Replace the single downcast with a source()-chain walk that finds
the io::Error at any depth, matching the same BrokenPipe /
ConnectionReset check already used for the direct IoError arm.
This commit is contained in:
yamabush1
2026-05-18 20:48:35 +02:00
parent 750eae7a93
commit 9cc65e70ea

View File

@@ -386,13 +386,25 @@ pub( crate ) fn try_run<A: App>( app: A ) -> Result<(), RunError>
Err( calloop::Error::OtherError( ref e ) ) => Err( calloop::Error::OtherError( ref e ) ) =>
{ {
// wayland-client surfaces the closed-socket condition as an // wayland-client surfaces the closed-socket condition as an
// OtherError wrapping an IoError rather than as the // OtherError wrapping a WaylandError::Io(BrokenPipe) — one
// calloop::Error::IoError variant handled above. Treat any // level deeper than a direct io::Error. Walk the source()
// BrokenPipe / ConnectionReset here the same way: exit cleanly. // chain so we catch it regardless of how many wrapper types
let is_closed = e.downcast_ref::<std::io::Error>() // sit between calloop and the raw io::Error.
.map( |io| matches!( io.kind(), let mut src: Option<&dyn std::error::Error> = Some( e.as_ref() );
std::io::ErrorKind::BrokenPipe | std::io::ErrorKind::ConnectionReset ) ) let mut is_closed = false;
.unwrap_or( false ); while let Some( err ) = src
{
if let Some( io ) = err.downcast_ref::<std::io::Error>()
{
if matches!( io.kind(),
std::io::ErrorKind::BrokenPipe | std::io::ErrorKind::ConnectionReset )
{
is_closed = true;
break;
}
}
src = err.source();
}
if is_closed if is_closed
{ {
eprintln!( "ltk: wayland connection lost; exiting" ); eprintln!( "ltk: wayland connection lost; exiting" );