Skip to content

Commit 8fe48e1

Browse files
authored
Merge pull request #247 from OpenKnots/okcode/fix-test-workspace-paths
Handle missing workspace paths in file tree watcher
2 parents d2bb63d + 63734eb commit 8fe48e1

2 files changed

Lines changed: 30 additions & 21 deletions

File tree

apps/server/src/wsServer.ts

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -855,26 +855,35 @@ export const createServer = Effect.fn(function* (): Effect.fn.Return<
855855

856856
let fileTreeDebounceTimer: ReturnType<typeof setTimeout> | null = null;
857857

858-
const fileTreeWatcher = fs.watch(cwd, { recursive: true }, (_eventType, filename) => {
859-
if (!filename) return;
860-
861-
// Ignore changes inside noisy directories
862-
const normalized = String(filename).replaceAll("\\", "/");
863-
const firstSegment = normalized.split("/")[0];
864-
if (firstSegment && IGNORED_WATCHER_DIRS.has(firstSegment)) return;
865-
866-
// Debounce rapid consecutive changes into a single push
867-
if (fileTreeDebounceTimer) clearTimeout(fileTreeDebounceTimer);
868-
fileTreeDebounceTimer = setTimeout(() => {
869-
fileTreeDebounceTimer = null;
870-
clearWorkspaceIndexCache(cwd);
871-
void Effect.runPromise(pushBus.publishAll(WS_CHANNELS.projectFileTreeChanged, { cwd }));
872-
}, FILE_TREE_DEBOUNCE_MS);
858+
// fs.watch throws ENOENT when the directory does not exist (e.g. in tests
859+
// or when a workspace path has been removed). Guard against this so the
860+
// server can still start up.
861+
const fileTreeWatcher = yield* Effect.sync(() => {
862+
try {
863+
return fs.watch(cwd, { recursive: true }, (_eventType, filename) => {
864+
if (!filename) return;
865+
866+
// Ignore changes inside noisy directories
867+
const normalized = String(filename).replaceAll("\\", "/");
868+
const firstSegment = normalized.split("/")[0];
869+
if (firstSegment && IGNORED_WATCHER_DIRS.has(firstSegment)) return;
870+
871+
// Debounce rapid consecutive changes into a single push
872+
if (fileTreeDebounceTimer) clearTimeout(fileTreeDebounceTimer);
873+
fileTreeDebounceTimer = setTimeout(() => {
874+
fileTreeDebounceTimer = null;
875+
clearWorkspaceIndexCache(cwd);
876+
void Effect.runPromise(pushBus.publishAll(WS_CHANNELS.projectFileTreeChanged, { cwd }));
877+
}, FILE_TREE_DEBOUNCE_MS);
878+
});
879+
} catch {
880+
return undefined;
881+
}
873882
});
874883

875884
yield* Effect.addFinalizer(() =>
876885
Effect.sync(() => {
877-
fileTreeWatcher.close();
886+
fileTreeWatcher?.close();
878887
if (fileTreeDebounceTimer) clearTimeout(fileTreeDebounceTimer);
879888
}),
880889
);

bun.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)