fix(event_loop): walk error source chain for BrokenPipe in OtherError
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:
@@ -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" );
|
||||||
|
|||||||
Reference in New Issue
Block a user