From 1a4f9493f56af684db37b119b939450dedbb4a0a Mon Sep 17 00:00:00 2001 From: Martin Tournoij Date: Thu, 21 Jul 2022 05:06:57 +0200 Subject: [PATCH] Use common error when removing an unwatched file (#460) The errors returned by the various implementations of the watcher are all different which makes handling them difficult. This PR follows the suggestion in: https://github.com/fsnotify/fsnotify/pull/455#issuecomment-1146037157 by @mattn to create a common error which is wrapped by the implementations. Replaces: https://github.com/fsnotify/fsnotify/pull/455 Signed-off-by: Andrew Thornton Co-authored-by: Andrew Thornton --- fsnotify.go | 3 ++- inotify.go | 2 +- inotify_test.go | 5 ++++- kqueue.go | 5 ++--- windows.go | 8 +++++--- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/fsnotify.go b/fsnotify.go index 0f4ee52e..b474b526 100644 --- a/fsnotify.go +++ b/fsnotify.go @@ -65,5 +65,6 @@ func (e Event) String() string { // Common errors that can be reported by a watcher var ( - ErrEventOverflow = errors.New("fsnotify queue overflow") + ErrNonExistentWatch = errors.New("can't remove non-existent watcher") + ErrEventOverflow = errors.New("fsnotify queue overflow") ) diff --git a/inotify.go b/inotify.go index a6d0e0ec..e6abddfd 100644 --- a/inotify.go +++ b/inotify.go @@ -134,7 +134,7 @@ func (w *Watcher) Remove(name string) error { // Remove it from inotify. if !ok { - return fmt.Errorf("can't remove non-existent inotify watch for: %s", name) + return fmt.Errorf("%w: %s", ErrNonExistentWatch, name) } // We successfully removed the watch if InotifyRmWatch doesn't return an diff --git a/inotify_test.go b/inotify_test.go index bb6db097..728f5c21 100644 --- a/inotify_test.go +++ b/inotify_test.go @@ -8,6 +8,7 @@ package fsnotify import ( + "errors" "fmt" "os" "path/filepath" @@ -303,6 +304,8 @@ func TestInotifyRemoveTwice(t *testing.T) { err = w.Remove(testFile) if err == nil { t.Fatalf("no error on removing invalid file") + } else if !errors.Is(err, ErrNonExistentWatch) { + t.Fatalf("unexpected error %v on removing invalid file", err) } w.mu.Lock() @@ -384,7 +387,7 @@ func TestInotifyOverflow(t *testing.T) { for dn := 0; dn < numDirs; dn++ { testSubdir := fmt.Sprintf("%s/%d", testDir, dn) - err := os.Mkdir(testSubdir, 0777) + err := os.Mkdir(testSubdir, 0o777) if err != nil { t.Fatalf("Cannot create subdir: %v", err) } diff --git a/kqueue.go b/kqueue.go index 6fb8d853..1b46acbd 100644 --- a/kqueue.go +++ b/kqueue.go @@ -74,7 +74,7 @@ func (w *Watcher) Close() error { w.isClosed = true // copy paths to remove while locked - var pathsToRemove = make([]string, 0, len(w.watches)) + pathsToRemove := make([]string, 0, len(w.watches)) for name := range w.watches { pathsToRemove = append(pathsToRemove, name) } @@ -107,7 +107,7 @@ func (w *Watcher) Remove(name string) error { watchfd, ok := w.watches[name] w.mu.Unlock() if !ok { - return fmt.Errorf("can't remove non-existent kevent watch for: %s", name) + return fmt.Errorf("%w: %s", ErrNonExistentWatch, name) } const registerRemove = unix.EV_DELETE @@ -442,7 +442,6 @@ func (w *Watcher) sendDirectoryChangeEvents(dirPath string) { for _, fileInfo := range files { filePath := filepath.Join(dirPath, fileInfo.Name()) err := w.sendFileCreatedEventIfNew(filePath, fileInfo) - if err != nil { return } diff --git a/windows.go b/windows.go index 7ff70093..1c1fe412 100644 --- a/windows.go +++ b/windows.go @@ -196,8 +196,10 @@ type watch struct { buf [4096]byte } -type indexMap map[uint64]*watch -type watchMap map[uint32]indexMap +type ( + indexMap map[uint64]*watch + watchMap map[uint32]indexMap +) func (w *Watcher) wakeupReader() error { e := syscall.PostQueuedCompletionStatus(w.port, 0, 0, nil) @@ -324,7 +326,7 @@ func (w *Watcher) remWatch(pathname string) error { watch := w.watches.get(ino) w.mu.Unlock() if watch == nil { - return fmt.Errorf("can't remove non-existent watch for: %s", pathname) + return fmt.Errorf("%w: %s", ErrNonExistentWatch, pathname) } if pathname == dir { w.sendEvent(watch.path, watch.mask&sysFSIGNORED)