Skip to content

Commit 89252df

Browse files
committed
fix(windows): add file flush delay to prevent ENOENT errors in tests
On Windows, file operations can be asynchronous at the OS level. After writeFile() completes, the file handle may not be fully released immediately, causing ENOENT errors when code tries to read the file right after writing. Enhanced retryWrite() to: - Add 10ms delay after writes on Windows to ensure file is flushed - Verify file accessibility with fsPromises.access() - Add fallback 10ms delay if file isn't accessible yet - Use node:timers/promises sleep instead of raw setTimeout This fixes the intermittent test failure in "should handle load -> update -> save workflow" on Windows CI runners.
1 parent 1fb817e commit 89252df

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

src/json/edit.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
* @fileoverview Editable JSON file manipulation with formatting preservation.
33
*/
44

5+
import { setTimeout as sleep } from 'node:timers/promises'
6+
57
import {
68
INDENT_SYMBOL,
79
NEWLINE_SYMBOL,
@@ -58,6 +60,21 @@ async function retryWrite(
5860
try {
5961
// eslint-disable-next-line no-await-in-loop
6062
await fsPromises.writeFile(filepath, content)
63+
// On Windows, add a small delay and verify file exists to ensure it's fully flushed
64+
// This prevents ENOENT errors when immediately reading after write
65+
if (process.platform === 'win32') {
66+
// eslint-disable-next-line no-await-in-loop
67+
await sleep(10)
68+
// Verify the file is actually readable
69+
try {
70+
// eslint-disable-next-line no-await-in-loop
71+
await fsPromises.access(filepath)
72+
} catch {
73+
// If file isn't accessible yet, wait a bit more
74+
// eslint-disable-next-line no-await-in-loop
75+
await sleep(10)
76+
}
77+
}
6178
return
6279
} catch (err) {
6380
const isLastAttempt = attempt === retries
@@ -74,7 +91,7 @@ async function retryWrite(
7491
// Exponential backoff: 10ms, 20ms, 40ms
7592
const delay = baseDelay * 2 ** attempt
7693
// eslint-disable-next-line no-await-in-loop
77-
await new Promise(resolve => setTimeout(resolve, delay))
94+
await sleep(delay)
7895
}
7996
}
8097
}

0 commit comments

Comments
 (0)