From b77da446d8b991e74bb1345cc2c9557daba84006 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fe=CC=81lix=20Saparelli?= Date: Sat, 12 Feb 2022 19:49:02 +1300 Subject: [PATCH] Split known create errors to get proper help text --- lib/src/error/specialised.rs | 34 ++++++++++++++++++++++++++-------- lib/src/fs.rs | 21 ++++++++++++--------- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/lib/src/error/specialised.rs b/lib/src/error/specialised.rs index 24780f5..906a67b 100644 --- a/lib/src/error/specialised.rs +++ b/lib/src/error/specialised.rs @@ -133,20 +133,38 @@ impl From for RuntimeError { #[diagnostic(url(docsrs))] pub enum FsWatcherError { /// Error received when creating a filesystem watcher fails. + /// + /// Also see `TooManyWatches` and `TooManyHandles`. #[error("failed to instantiate")] #[diagnostic( code(watchexec::fs_watcher::create), help("perhaps retry with the poll watcher") )] - Create { - /// The underlying error. - #[source] - err: notify::Error, + Create(#[source] notify::Error), - /// A hint to the user about resolving the error. - #[source_code] - help: String, - }, + /// Error received when creating or updating a filesystem watcher fails because there are too many watches. + /// + /// This is the OS error 28 on Linux. + #[error("failed to instantiate: too many watches")] + #[diagnostic(code(watchexec::fs_watcher::too_many_watches))] + #[cfg_attr(target_os = "linux", diagnostic(help("you will want to increase your inotify.max_user_watches, see inotify(7) and https://watchexec.github.io/docs/inotify-limits.html")))] + #[cfg_attr( + not(target_os = "linux"), + diagnostic(help("this should not happen on your platform")) + )] + TooManyWatches(#[source] notify::Error), + + /// Error received when creating or updating a filesystem watcher fails because there are too many file handles open. + /// + /// This is the OS error 24 on Linux. It may also occur when the limit for inotify instances is reached. + #[error("failed to instantiate: too many handles")] + #[diagnostic(code(watchexec::fs_watcher::too_many_handles))] + #[cfg_attr(target_os = "linux", diagnostic(help("you will want to increase your `nofile` limit, see pam_limits(8); or increase your inotify.max_user_instances, see inotify(7) and https://watchexec.github.io/docs/inotify-limits.html")))] + #[cfg_attr( + not(target_os = "linux"), + diagnostic(help("this should not happen on your platform")) + )] + TooManyHandles(#[source] notify::Error), /// Error received when reading a filesystem event fails. #[error("received an event that we could not read")] diff --git a/lib/src/fs.rs b/lib/src/fs.rs index cd00035..6c2a5c1 100644 --- a/lib/src/fs.rs +++ b/lib/src/fs.rs @@ -53,16 +53,19 @@ impl Watcher { } .map_err(|err| RuntimeError::FsWatcher { kind: self, - err: FsWatcherError::Create { - help: if cfg!(target_os = "linux") && (matches!(err.kind, notify::ErrorKind::MaxFilesWatch) || matches!(err.kind, notify::ErrorKind::Io(ref ioerr) if ioerr.raw_os_error() == Some(28))) { - "you will want to increase your inotify.max_user_watches, see inotify(7) and https://watchexec.github.io/docs/inotify-limits.html" - } else if cfg!(target_os = "linux") && matches!(err.kind, notify::ErrorKind::Io(ref ioerr) if ioerr.raw_os_error() == Some(24)) { - "you will want to increase your `nofile` limit, see pam_limits(8)" + err: if cfg!(target_os = "linux") + && (matches!(err.kind, notify::ErrorKind::MaxFilesWatch) + || matches!(err.kind, notify::ErrorKind::Io(ref ioerr) if ioerr.raw_os_error() == Some(28))) + { + FsWatcherError::TooManyWatches(err) + } else if cfg!(target_os = "linux") + && matches!(err.kind, notify::ErrorKind::Io(ref ioerr) if ioerr.raw_os_error() == Some(24)) + { + FsWatcherError::TooManyHandles(err) } else { - "you may want to try again with the polling watcher" - }.into(), - err, - }}) + FsWatcherError::Create(err) + }, + }) } }