From d22616dff092cf0fda4dd45a60ff972fa8123d69 Mon Sep 17 00:00:00 2001 From: wuyangfan <1102042793@qq.com> Date: Sun, 17 May 2026 16:35:37 +0800 Subject: [PATCH] fix: avoid panic when filesystem watcher hits permission errors Log and disable notify-based updates instead of panicking when the watcher cannot be created or cannot recurse into permission-denied directories (e.g. podman-owned folders with --watcher). Fixes #2900 Co-authored-by: Cursor --- src/watcher.rs | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/watcher.rs b/src/watcher.rs index ea30c7f135..e0b229433e 100644 --- a/src/watcher.rs +++ b/src/watcher.rs @@ -49,15 +49,20 @@ impl RepoWatcher { loop { let ev = receiver.recv()?; - if let Ok(ev) = ev { - log::debug!("notify events: {}", ev.len()); + match ev { + Ok(events) => { + log::debug!("notify events: {}", events.len()); - for (idx, ev) in ev.iter().enumerate() { - log::debug!("notify [{idx}]: {ev:?}"); - } + for (idx, event) in events.iter().enumerate() { + log::debug!("notify [{idx}]: {event:?}"); + } - if !ev.is_empty() { - sender.send(())?; + if !events.is_empty() { + sender.send(())?; + } + } + Err(e) => { + log::warn!("notify debouncer error: {e}"); } } } @@ -71,12 +76,27 @@ fn create_watcher( ) { scope_time!("create_watcher"); - let mut bouncer = - new_debouncer(timeout, tx).expect("Watch create error"); - bouncer + let mut bouncer = match new_debouncer(timeout, tx) { + Ok(bouncer) => bouncer, + Err(e) => { + log::warn!( + "failed to create filesystem watcher: {e}; \ + file change notifications disabled" + ); + return; + } + }; + + if let Err(e) = bouncer .watcher() - .watch(Path::new(&workdir), RecursiveMode::Recursive) - .expect("Watch error"); + .watch(Path::new(workdir), RecursiveMode::Recursive) + { + log::warn!( + "failed to watch repository for changes ({e}); \ + file change notifications disabled" + ); + return; + } std::mem::forget(bouncer); }