Repository navigation
fix: stop the fs.watch retry loop behind a dangling directory symlink - #346
Conversation
🦋 Changeset detectedLatest commit: 2f54d37 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 14 minutes. View limit details
WalkthroughDirectoryWatcher now retries watcher creation once per second when a watched path is not a directory. It creates and scans the watcher when the path becomes available, and clears pending retries when closed. The declarations include the retry method and timer property. Tests cover retry frequency, change reporting, link removal, and watcher closure. Priority: ➖ Normal Severity of issue fixed: Medium Merge Risk: 🔵 Low · up to
|
There was a problem hiding this comment.
Actionable comments posted: 2
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Organization UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
2678ecd2-a553-4bf1-a0cf-56d46f27de31
📒 Files selected for processing (4)
.changeset/dangling-symlink-retry-loop.mdlib/DirectoryWatcher.jstest/Watchpack.test.jstypes/DirectoryWatcher.d.ts
Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review.
Merging this PR will not alter performance
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #346 +/- ##
==========================================
+ Coverage 92.24% 92.45% +0.20%
==========================================
Files 8 8
Lines 1315 1338 +23
Branches 391 396 +5
==========================================
+ Hits 1213 1237 +24
+ Misses 96 95 -1
Partials 6 6
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Organization UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
b15cd850-bd9c-498a-a7ba-aae1aaaf4c61
📒 Files selected for processing (1)
test/Watchpack.test.js
Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 0 remain after this review.
Treat any path that is not a directory yet like a dangling symlink, and cover both retry guards.
There was a problem hiding this comment.
Actionable comments posted: 2
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Organization UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
f771df8c-ad5b-4589-9d4c-9fef7e63f3bf
📒 Files selected for processing (4)
lib/DirectoryWatcher.jstest/DirectoryWatcherExtra.test.jstest/Watchpack.test.jstypes/DirectoryWatcher.d.ts
Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 0 remain after this review.
Summary
Fixes #342.
Watching through a dangling directory symlink looped forever:
fs.watch(link)follows the link and fails withENOENT, so the watcher falls back towatchInParentDirectory()withstartTime = 1.link(anlstatof the symlink succeeds), so it reports it as "outdated on attach" right away.createWatcher(), which fails again, and the cycle repeats.The parent watcher now retries at once only when the path is really a directory. If the path exists but is not a directory yet (a dangling symlink, or a regular file), it re-checks once a second, because the path becoming a directory emits nothing on the path itself. The timer is cleared on
close(). This also fixes a missing directory that reappears as a file: before, that loggedWatchpack Error (initial scan): ENOTDIRand never reported files created after the path became a directory (as raised in review).fs.watchcalls in 3 sENOTDIRlogged, later file never reportedWhat kind of change does this PR introduce?
fix
Did you add tests for your changes?
Yes.
test/Watchpack.test.jsgets a "path that is not a directory yet" block: waiting behind a dangling symlink without a retry loop (3,812fs.watchcalls without the fix), a path that first appears as a file, and no further retries once the link is removed or the watcher is closed.test/DirectoryWatcherExtra.test.jscovers both retry guards. Every changed line and branch is covered. The full suite passes with native watching (203) and withWATCHPACK_POLLING=200(199).Does this PR introduce a breaking change?
No.
If relevant, what needs to be documented once your changes are merged or what have you already documented?
n/a
Use of AI
Claude Code reproduced the loop, traced it to the parent-watcher retry, and wrote the fix and the tests, including the file case CodeRabbit raised. A maintainer asked for the fix.
🤖 Generated with Claude Code
https://claude.ai/code/session_016ZdAw4de2GgWu4X7BMY8ys
Summary by CodeRabbit