Repository: sxyazi/yazi
File: yazi-watcher/src/local/local.rs (Rust)

Code before:
		};

		let primary = RecommendedWatcher::new(handler.clone(), config);
		let alternative = PollWatcher::new(handler, config).unwrap();

		if let Err(e) = &primary {
			error!("Failed to initialize primary watcher: {e:?}");
		}

		Self { primary: primary.ok(), alternative }
	}

	pub(crate) fn watch(&mut self, watchee: &mut Watchee) -> Result<()> {
		let (path, alt) =
			watchee.as_local_mut().ok_or_else(|| notify::Error::generic("Not a local watchee"))?;

		if let Some(primary) = self.primary.as_mut().filter(|_| !*alt) {
			match primary.watch(path, RecursiveMode::NonRecursive) {
				Ok(()) => return Ok(()),
				Err(e) => tracing::warn!("Failed to watch {path:?} with primary watcher: {e:?}"),
			}
		}

		tracing::debug!("Watching {path:?} with alternative watcher");
		*alt = true;
		self.alternative.watch(path, RecursiveMode::NonRecursive)
	}

	pub(crate) fn unwatch(&mut self, watchee: &Watchee) -> Result<()> {
		let (path, alt) =
			watchee.as_local().ok_or_else(|| notify::Error::generic("Not a local watchee"))?;

		let result = if alt {
			self.alternative.unwatch(path)
		} else if let Some(primary) = &mut self.primary {
			primary.unwatch(path)
		} else {
			Ok(())
		};

		match result {
			Ok(()) => Ok(()),
			Err(e) if matches!(e.kind, notify::ErrorKind::WatchNotFound) => Ok(()),
			Err(e) => Err(e)?,
		}
	}

	pub(crate) fn heuristic(path: &Path) -> bool {
		if cfg!(target_os = "netbsd") || yazi_adapter::WSL.get() {
			return true;
		}

Review comment (bug):
`Local::watch()` now logs a warning on any primary watcher error and then falls back to the poll watcher. This includes expected `PathNotFound` cases that were previously handled silently, which can create noisy logs when paths are transient/missing. Consider special-casing `ErrorKind::PathNotFound` (and possibly `WatchNotFound`) to avoid warning-level logs (and/or return `Ok(())` like before) while still allowing the fallback behavior for real failures.

Code after:
		};

		let primary = RecommendedWatcher::new(handler.clone(), config);
		let alternative = PollWatcher::new(handler, config).unwrap();

		if let Err(e) = &primary {
			error!("Failed to initialize primary watcher: {e:?}");
		}

		Self { primary: primary.ok(), alternative }
	}

	pub(crate) fn watch(&mut self, watchee: &mut Watchee) -> Result<()> {
		let (path, alt) =
			watchee.as_local_mut().ok_or_else(|| notify::Error::generic("Not a local watchee"))?;

		if let Some(primary) = self.primary.as_mut().filter(|_| !*alt) {
			match primary.watch(path, RecursiveMode::NonRecursive) {
				Ok(()) => return Ok(()),
				Err(e) => tracing::warn!("Failed to watch {path:?} with primary watcher: {e:?}"),
			}
		}

		tracing::debug!("Watching {path:?} with alternative watcher");
		*alt = true;
		self.alternative.watch(path, RecursiveMode::NonRecursive)
	}

	pub(crate) fn unwatch(&mut self, watchee: &Watchee) -> Result<()> {
		let (path, alt) =
			watchee.as_local().ok_or_else(|| notify::Error::generic("Not a local watchee"))?;

		let result = if alt {
			self.alternative.unwatch(path)
		} else if let Some(primary) = &mut self.primary {
			primary.unwatch(path)
		} else {
			Ok(())
		};

		match result {
			Ok(()) => Ok(()),
			Err(e) if matches!(e.kind, notify::ErrorKind::WatchNotFound) => Ok(()),
			Err(e) => Err(e)?,
		}
	}

	pub(crate) fn soundless(path: &Path) -> bool {
		if cfg!(target_os = "netbsd") || yazi_adapter::WSL.get() {
			return true;
		}