mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 20:42:43 +00:00
The update poller and the chunk-error reload guard key on the target version instead of disarming for the whole session, so a second deploy re-arms the self-heal and a stale shell can no longer strand with 404ing chunks. Lazy chart imports retry once and mount inside a per-card error boundary with a reload affordance — a failed chunk degrades to one card instead of replacing the page. The JSON API client attaches a fifteen-second timeout unless the caller brings its own signal (the raw streaming path is exempt), chart queries surface errors with a retry instead of rendering as an empty period, per-type fetch failures reject instead of caching an empty series as fresh, and the session and snapshot queries retry once on transient network or server errors.
33 lines
1.1 KiB
TypeScript
33 lines
1.1 KiB
TypeScript
/**
|
|
* Retrying wrapper for lazy chunk imports.
|
|
*
|
|
* A rejected `import()` inside `React.lazy` / `next/dynamic` caches its
|
|
* rejection on the component instance, so one transient chunk 404 (a
|
|
* stale shell right after a deploy, a flaky connection) bricks the lazy
|
|
* boundary for the rest of the session — remounting never re-attempts
|
|
* the import. Wrapping the importer here absorbs the transient class:
|
|
* the import retries once after a short delay before the rejection is
|
|
* allowed to surface to the boundary's error handling.
|
|
*/
|
|
|
|
export const IMPORT_RETRY_DELAY_MS = 1_000;
|
|
|
|
/**
|
|
* Run `importer`, retrying `retries` more times (default once) after
|
|
* `delayMs` when it rejects. The final rejection propagates unchanged
|
|
* so the caller's error boundary sees the original chunk error.
|
|
*/
|
|
export async function importWithRetry<T>(
|
|
importer: () => Promise<T>,
|
|
retries = 1,
|
|
delayMs = IMPORT_RETRY_DELAY_MS,
|
|
): Promise<T> {
|
|
try {
|
|
return await importer();
|
|
} catch (err) {
|
|
if (retries <= 0) throw err;
|
|
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
return importWithRetry(importer, retries - 1, delayMs);
|
|
}
|
|
}
|