Skip to content

Commit 38cb0fd

Browse files
committed
build(mac): retry notarization on transient network errors
1 parent 5c3886c commit 38cb0fd

File tree

1 file changed

+37
-1
lines changed

1 file changed

+37
-1
lines changed

scripts/notarize.js

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,42 @@
11
const path = require('path');
22
const { notarize } = require('@electron/notarize');
33

4+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
5+
6+
async function notarizeWithRetry(options, { attempts = 5 } = {}) {
7+
let lastError;
8+
9+
for (let attempt = 1; attempt <= attempts; attempt++) {
10+
try {
11+
await notarize(options);
12+
return;
13+
} catch (error) {
14+
lastError = error;
15+
const message =
16+
(error && (error.stack || error.message)) ||
17+
(typeof error === 'string' ? error : JSON.stringify(error));
18+
19+
const isLikelyTransient = /NSURLErrorDomain|offline|No network route|ECONNRESET|ETIMEDOUT|EAI_AGAIN|ENOTFOUND|statusCode:\s*nil/i.test(
20+
message || ''
21+
);
22+
23+
if (!isLikelyTransient || attempt === attempts) {
24+
throw error;
25+
}
26+
27+
const delayMs = Math.min(5 * 60 * 1000, 15_000 * Math.pow(2, attempt - 1));
28+
console.warn(
29+
`[notarize] attempt ${attempt}/${attempts} failed (likely transient). Retrying in ${Math.round(
30+
delayMs / 1000
31+
)}s...\n${message}`
32+
);
33+
await sleep(delayMs);
34+
}
35+
}
36+
37+
throw lastError;
38+
}
39+
440
module.exports = async function notarizing(context) {
541
if (process.platform !== 'darwin') return;
642

@@ -16,7 +52,7 @@ module.exports = async function notarizing(context) {
1652
const appName = packager.appInfo.productFilename;
1753
const appPath = path.join(appOutDir, `${appName}.app`);
1854

19-
await notarize({
55+
await notarizeWithRetry({
2056
appPath,
2157
appleApiKey: appleApiKeyPath,
2258
appleApiKeyId,

0 commit comments

Comments
 (0)