Skip to content

Commit 0c0f89e

Browse files
committed
build: improve retry exec logic
Prior to this change, there was a flaw in its handling of the retry logic, specifically within the `setTimeout` block. The function had a recursive promise resolution problem and an incorrect handling of the rejected state.
1 parent 653b483 commit 0c0f89e

File tree

1 file changed

+27
-24
lines changed

1 file changed

+27
-24
lines changed

scripts/windows-testing/convert-symlinks.mjs

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import childProcess from 'node:child_process';
2525
import fs from 'node:fs/promises';
2626
import path from 'node:path';
27+
import { setTimeout } from 'node:timers/promises';
2728

2829
const [rootDir, cmdPath] = process.argv.slice(2);
2930

@@ -93,32 +94,34 @@ async function transformDir(p) {
9394
await Promise.all(directoriesToVisit.map((d) => transformDir(d)));
9495
}
9596

96-
function exec(cmd, maxRetries = 5, retryDelay = 200) {
97-
return new Promise((resolve, reject) => {
98-
childProcess.exec(cmd, { cwd: rootDir }, (error) => {
99-
if (error !== null) {
100-
// Windows command spawned within WSL (which is untypical) seem to be flaky rarely.
101-
// This logic tries to make it fully stable by re-trying if this surfaces:
102-
// See: https://github.com/microsoft/WSL/issues/8677.
103-
if (
104-
maxRetries > 0 &&
105-
error.stderr !== undefined &&
106-
error.stderr.includes(`accept4 failed 110`)
107-
) {
108-
// Add a small delay before the retry
109-
setTimeout(() => {
110-
resolve(exec(cmd, maxRetries - 1, retryDelay));
111-
}, retryDelay);
112-
113-
return;
114-
}
115-
116-
reject(error);
97+
async function exec(cmd, maxRetries = 5, retryDelay = 100) {
98+
let attempts = 0;
99+
while (attempts <= maxRetries) {
100+
try {
101+
await new Promise((resolve, reject) => {
102+
childProcess.exec(cmd, { cwd: rootDir }, (error) => {
103+
if (error) {
104+
reject(error);
105+
} else {
106+
resolve();
107+
}
108+
});
109+
});
110+
111+
return;
112+
} catch (error) {
113+
// Windows command spawned within WSL (which is untypical) seem to be flaky.
114+
// This logic tries to make it fully stable by re-trying if this surfaces:
115+
// See: https://github.com/microsoft/WSL/issues/8677.
116+
if (attempts < maxRetries && error.stderr?.includes('accept4 failed 110')) {
117+
// Add a delay before the next attempt
118+
await setTimeout(retryDelay);
119+
attempts++;
117120
} else {
118-
resolve();
121+
throw error;
119122
}
120-
});
121-
});
123+
}
124+
}
122125
}
123126

124127
try {

0 commit comments

Comments
 (0)