Skip to content

Commit 83c6333

Browse files
mussonkingclaude
andcommitted
fix: fall back from WSL workspace watch failures
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 8249043 commit 83c6333

2 files changed

Lines changed: 10 additions & 7 deletions

File tree

apps/desktop/src/main/workspace-watcher.test.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,15 +161,18 @@ describe('files-watcher subscribe / unsubscribe', () => {
161161
expect(__test.watchers.has('d1')).toBe(false);
162162
});
163163

164-
it('falls back to polling when native watch is denied by permissions', () => {
164+
it.each([
165+
['permission denial', 'EPERM'],
166+
['unsupported directory watch', 'EISDIR'],
167+
])('falls back to polling when native watch fails from %s', (_reason, code) => {
165168
reset();
166-
const err = Object.assign(new Error('operation not permitted'), { code: 'EPERM' });
169+
const err = Object.assign(new Error('watch unavailable'), { code });
167170
watchMock.mockImplementation(() => {
168171
throw err;
169172
});
170173
getDesignMock.mockReturnValue({
171174
id: 'd1',
172-
workspacePath: tempWorkspace('codesign-watch-eperm'),
175+
workspacePath: tempWorkspace(`codesign-watch-${code.toLowerCase()}`),
173176
});
174177
registerFilesWatcherIpc({} as never, () => null);
175178
const sub = getHandler('codesign:files:v1:subscribe');

apps/desktop/src/main/workspace-watcher.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ function toForwardSlashes(path: string): string {
6565
return sep === '/' ? path : path.split(sep).join('/');
6666
}
6767

68-
function isPermissionWatchError(err: unknown): boolean {
68+
function shouldFallbackToPolling(err: unknown): boolean {
6969
const code = (err as NodeJS.ErrnoException).code;
70-
return code === 'EPERM' || code === 'EACCES';
70+
return code === 'EPERM' || code === 'EACCES' || code === 'EISDIR';
7171
}
7272

7373
function isWorkspaceUnavailableWatchError(err: unknown): boolean {
@@ -183,7 +183,7 @@ function startWatcher(
183183
workspacePath,
184184
error: err instanceof Error ? err.message : String(err),
185185
});
186-
if (isPermissionWatchError(err)) {
186+
if (shouldFallbackToPolling(err)) {
187187
watchers.set(designId, entry);
188188
startPolling(designId, entry, getWin);
189189
return { ok: true, entry };
@@ -196,7 +196,7 @@ function startWatcher(
196196
entry.watcher = watcher;
197197
watcher.on('error', (err) => {
198198
log.warn('files.watch.error', { designId, error: String(err) });
199-
if (!isPermissionWatchError(err)) return;
199+
if (!shouldFallbackToPolling(err)) return;
200200
const active = watchers.get(designId);
201201
if (!active || active.watcher !== watcher) return;
202202
try {

0 commit comments

Comments
 (0)