Skip to content

Commit 7f4ab11

Browse files
committed
refactor: use p-retry library for extension fetch with exponential backoff like netlify/edge-bundler
1 parent a3085d9 commit 7f4ab11

File tree

2 files changed

+20
-28
lines changed

2 files changed

+20
-28
lines changed

packages/config/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
"map-obj": "^5.0.0",
7777
"omit.js": "^2.0.2",
7878
"p-locate": "^6.0.0",
79+
"p-retry": "^6.0.0",
7980
"path-type": "^6.0.0",
8081
"read-package-up": "^11.0.0",
8182
"tomlify-j0.4": "^3.0.0",

packages/config/src/api/site_info.ts

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { NetlifyAPI } from '@netlify/api'
2-
2+
import pRetry, { AbortError } from 'p-retry'
33
import * as z from 'zod'
44

55
import { getEnvelope } from '../env/envelope.js'
@@ -247,34 +247,25 @@ export const getExtensions = async function ({
247247
headers.set('Netlify-SDK-Build-Bot-Token', token)
248248
}
249249

250-
// Retry with exponential backoff for transient network issues
251-
const maxRetries = 3
252-
let lastError: Error | undefined
253-
for (let attempt = 0; attempt < maxRetries; attempt++) {
254-
try {
255-
const res = await fetch(url, { headers })
256-
if (res.status === 200) {
257-
return ExtensionResponseSchema.parse(await res.json())
258-
}
259-
// Dont do retry on 4xx errors
260-
if (res.status >= 400 && res.status < 500) {
261-
throw new Error(`Unexpected status code ${res.status} from fetching extensions`)
262-
}
263-
lastError = new Error(`Unexpected status code ${res.status} from fetching extensions`)
264-
} catch (err) {
265-
lastError = err instanceof Error ? err : new Error('unknown error')
266-
// Dont do retry on 4xx errors
267-
if (lastError.message.includes('4')) {
268-
break
269-
}
270-
}
271-
if (attempt < maxRetries - 1) {
272-
await new Promise((resolve) => setTimeout(resolve, 1000 * Math.pow(2, attempt)))
273-
}
274-
}
275-
{
250+
try {
251+
return await pRetry(
252+
async () => {
253+
const res = await fetch(url, { headers })
254+
if (res.status === 200) {
255+
return ExtensionResponseSchema.parse(await res.json())
256+
}
257+
const errorMsg = `Unexpected status code ${res.status} from fetching extensions`
258+
// Don't retry on 4xx errors (client errors)
259+
if (res.status >= 400 && res.status < 500) {
260+
throw new AbortError(errorMsg)
261+
}
262+
throw new Error(errorMsg)
263+
},
264+
{ retries: 3 },
265+
)
266+
} catch (err) {
276267
return throwUserError(
277-
`Failed retrieving extensions for site ${siteId}: ${lastError?.message ?? 'unknown error'}. ${ERROR_CALL_TO_ACTION}`,
268+
`Failed retrieving extensions for site ${siteId}: ${err instanceof Error ? err.message : 'unknown error'}. ${ERROR_CALL_TO_ACTION}`,
278269
)
279270
}
280271
}

0 commit comments

Comments
 (0)