mirror of
https://github.com/ThatGuySam/doesitarm.git
synced 2026-05-18 06:44:46 -07:00
The TypeScript helper refactor exposed a separate production risk: builds can fail when the sitemap-endpoints API returns a transient 5xx during Pagefind index generation. Move that fetch into a small helper with retry logic and add a focused prebuild test so this failure mode is caught without waiting on a full deploy. Constraint: Must keep Pagefind index generation behavior the same when the endpoint is healthy Rejected: Ignore the failure as external-only | transient 5xx responses can still block deploys and CI repeatedly Confidence: high Scope-risk: narrow Reversibility: clean Directive: When external build inputs can fail transiently, add a small retryable helper plus a direct test before relying on full deploy verification Tested: pnpm exec vitest run test/prebuild/load-sitemap-endpoints.test.ts; pnpm run typecheck; pnpm run test-prebuild Not-tested: Full production redeploy completion before push
63 lines
1.5 KiB
TypeScript
63 lines
1.5 KiB
TypeScript
import fs from 'fs-extra'
|
|
import axios from 'axios'
|
|
|
|
import {
|
|
sitemapEndpointsPath
|
|
} from '~/helpers/pagefind/config.js'
|
|
|
|
function shouldRetryError ( error: unknown ) {
|
|
const status = ( error as { response?: { status?: number } } )?.response?.status
|
|
|
|
return typeof status === 'number' && status >= 500
|
|
}
|
|
|
|
async function fetchJsonWithRetries (
|
|
url: string,
|
|
{
|
|
attempts = 3,
|
|
delayMs = 1000
|
|
}: {
|
|
attempts?: number
|
|
delayMs?: number
|
|
} = {}
|
|
) {
|
|
let lastError: unknown
|
|
|
|
for ( let attempt = 1; attempt <= attempts; attempt += 1 ) {
|
|
try {
|
|
const response = await axios.get( url )
|
|
|
|
return response.data
|
|
} catch ( error ) {
|
|
lastError = error
|
|
|
|
if ( attempt >= attempts || !shouldRetryError( error ) ) {
|
|
throw error
|
|
}
|
|
|
|
await new Promise( resolve => setTimeout( resolve, delayMs ) )
|
|
}
|
|
}
|
|
|
|
throw lastError
|
|
}
|
|
|
|
export async function loadSitemapEndpoints () {
|
|
if ( await fs.pathExists( sitemapEndpointsPath ) ) {
|
|
return await fs.readJson( sitemapEndpointsPath )
|
|
}
|
|
|
|
if ( !process.env.PUBLIC_API_DOMAIN ) {
|
|
throw new Error(`Missing ${ sitemapEndpointsPath } and PUBLIC_API_DOMAIN is not set`)
|
|
}
|
|
|
|
const apiUrl = new URL( process.env.PUBLIC_API_DOMAIN )
|
|
apiUrl.pathname = sitemapEndpointsPath.replace(/^\.?\/?static\//, '/')
|
|
|
|
return await fetchJsonWithRetries( apiUrl.toString() )
|
|
}
|
|
|
|
export {
|
|
fetchJsonWithRetries,
|
|
shouldRetryError
|
|
}
|