cloudflare-next-intl 0.8.49 → 0.8.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/src/error_handling/install_console_error_override.d.ts +10 -0
- package/dist/src/error_handling/install_console_error_override.js +29 -1
- package/dist/src/error_handling/is_stale_deploy_error.js +1 -0
- package/dist/src/error_handling/stringify_unknown.js +4 -0
- package/llms.txt +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -527,7 +527,7 @@ export default function GlobalError({
|
|
|
527
527
|
}
|
|
528
528
|
```
|
|
529
529
|
|
|
530
|
-
- `isStaleDeployError(error:
|
|
530
|
+
- `isStaleDeployError(error: unknown, patterns?: readonly string[]): boolean`: Returns `true` if the error indicates a missing chunk, failed fetch, dynamically imported module failure, CSS chunk failure, closed connection, corrupted RSC payload, hydration error #412 from a stale deployment, or an aborted stream missing an error value (`undefined`). Defaults to `defaultStaleDeployPatterns` (or patterns configured in `intl-config.ts` via `errorHandling.staleDeployPatterns`).
|
|
531
531
|
- `setStaleDeployPatterns(patterns: readonly string[]): void`: Setter to update the active pattern list and pre-compute lowercased substrings for maximum runtime performance.
|
|
532
532
|
- `getStaleDeployPatterns(): readonly string[]`: Returns the currently active pattern list.
|
|
533
533
|
- `clearClientCache(): Promise<void>`: Best-effort cleanup that deletes all CacheStorage caches (`window.caches`), unregisters active Service Workers, and clears `sessionStorage`.
|
|
@@ -557,8 +557,8 @@ export default function GlobalError({
|
|
|
557
557
|
}
|
|
558
558
|
```
|
|
559
559
|
|
|
560
|
-
- `useStaleDeployRecovery(error:
|
|
561
|
-
- `shouldRecoverFromStaleDeploy(error:
|
|
560
|
+
- `useStaleDeployRecovery(error: unknown, onRecover?: () => Promise<unknown>, delayMs = 5000): boolean`: Detects a stale-deploy error via `isStaleDeployError` and, **once per build id**, waits `delayMs`, runs `onRecover` (if provided) and `clearClientCache` in parallel, then reloads the page. The build id is read from `localStorage['buildId']` (set by `IntlHelperScript`'s `BUILD_ID` check) and a `sessionStorage` marker records which build id already spent its reload, so a repeat failure on the same build falls through to `false` (render your normal error UI) instead of reloading forever. A redeploy changes the build id and re-arms exactly one more attempt. **Exception:** if the build id was written within the last 60 seconds (`localStorage['buildIdSetAt']`, also set by `IntlHelperScript`), the hook recovers anyway — a stale-deploy error moments after adopting a new build is the deploy still settling, not a real failure, so the one-reload cap is bypassed for that window.
|
|
561
|
+
- `shouldRecoverFromStaleDeploy(error: unknown, buildId: string, marker: string | null, recentBuild = false): boolean`: The pure predicate behind the hook, exported for testing.
|
|
562
562
|
- `isRecentBuild(setAt: number | null, now: number, windowMs = 60000): boolean`: Whether `setAt` (typically `buildIdSetAt`) falls within `windowMs` of `now`.
|
|
563
563
|
|
|
564
564
|
### Database (`db`)
|
|
@@ -45,4 +45,14 @@ import { type ReportErrorConfig } from './report_error';
|
|
|
45
45
|
* `getCloudflareContext`/`ctx.waitUntil` available in the browser, so
|
|
46
46
|
* client-side reports always await `onError` directly.
|
|
47
47
|
*/
|
|
48
|
+
/**
|
|
49
|
+
* Logged in place of a bare `undefined` when something calls
|
|
50
|
+
* `console.error()` with no arguments (or a single `undefined`) — an
|
|
51
|
+
* aborted RSC stream on a stale deploy does exactly this, leaving an
|
|
52
|
+
* unactionable `undefined` line in devtools. The raw value is still passed
|
|
53
|
+
* to `reportError` unchanged: `isStaleDeployError` treats exactly
|
|
54
|
+
* `undefined` as a stale deploy, so substituting a string here would break
|
|
55
|
+
* the recovery reload.
|
|
56
|
+
*/
|
|
57
|
+
export declare const EMPTY_CONSOLE_ERROR_MESSAGE = "console.error called with no message";
|
|
48
58
|
export default function installConsoleErrorOverride(config: ReportErrorConfig | undefined, isClient?: boolean): void;
|
|
@@ -45,6 +45,29 @@ import reportError, { consoleOverrideState } from './report_error';
|
|
|
45
45
|
* `getCloudflareContext`/`ctx.waitUntil` available in the browser, so
|
|
46
46
|
* client-side reports always await `onError` directly.
|
|
47
47
|
*/
|
|
48
|
+
/**
|
|
49
|
+
* Logged in place of a bare `undefined` when something calls
|
|
50
|
+
* `console.error()` with no arguments (or a single `undefined`) — an
|
|
51
|
+
* aborted RSC stream on a stale deploy does exactly this, leaving an
|
|
52
|
+
* unactionable `undefined` line in devtools. The raw value is still passed
|
|
53
|
+
* to `reportError` unchanged: `isStaleDeployError` treats exactly
|
|
54
|
+
* `undefined` as a stale deploy, so substituting a string here would break
|
|
55
|
+
* the recovery reload.
|
|
56
|
+
*/
|
|
57
|
+
export const EMPTY_CONSOLE_ERROR_MESSAGE = 'console.error called with no message';
|
|
58
|
+
/**
|
|
59
|
+
* The frames BELOW this override — i.e. whoever actually called
|
|
60
|
+
* `console.error`. Devtools blames this module for every forwarded call
|
|
61
|
+
* (the real `console.error` runs from here), so an argument-less call left
|
|
62
|
+
* nothing but a bare `undefined` line pointing at this file. Captured
|
|
63
|
+
* lazily, only for that case.
|
|
64
|
+
*/
|
|
65
|
+
function callerStack() {
|
|
66
|
+
const stack = new Error().stack;
|
|
67
|
+
if (!stack)
|
|
68
|
+
return '';
|
|
69
|
+
return `\n${stack.split('\n').slice(3).join('\n')}`;
|
|
70
|
+
}
|
|
48
71
|
export default function installConsoleErrorOverride(config, isClient) {
|
|
49
72
|
if (config?.errorHandling?.overrideConsoleError !== true)
|
|
50
73
|
return;
|
|
@@ -55,7 +78,12 @@ export default function installConsoleErrorOverride(config, isClient) {
|
|
|
55
78
|
const suppressOnClient = isClient === true && config.errorHandling?.suppressClientConsoleError === true;
|
|
56
79
|
const override = (message, ...optionalParams) => {
|
|
57
80
|
if (!suppressOnClient) {
|
|
58
|
-
|
|
81
|
+
if (message === undefined && optionalParams.length === 0) {
|
|
82
|
+
originalConsoleError(`${EMPTY_CONSOLE_ERROR_MESSAGE}${callerStack()}`);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
originalConsoleError(message, ...optionalParams);
|
|
86
|
+
}
|
|
59
87
|
}
|
|
60
88
|
void reportError(config, { error: message, classOrMethodName: 'Global Console Error Handler', params: optionalParams, isClient });
|
|
61
89
|
};
|
|
@@ -30,6 +30,10 @@ function resolveFunctionError(value) {
|
|
|
30
30
|
* so a single unserializable nested value can't crash the whole report.
|
|
31
31
|
*/
|
|
32
32
|
export default function stringifyUnknown(value, isClient, isNested = false) {
|
|
33
|
+
if (value === undefined)
|
|
34
|
+
return 'undefined';
|
|
35
|
+
if (value === null)
|
|
36
|
+
return 'null';
|
|
33
37
|
if (typeof value === 'string')
|
|
34
38
|
return stripAnsiCodes(value);
|
|
35
39
|
if (value instanceof Error)
|
package/llms.txt
CHANGED
|
@@ -29,7 +29,7 @@ other subpath can be used.
|
|
|
29
29
|
- `./dbHelpers` — generic Drizzle SQL helper functions (`excluded`, `onConflictSet`, `ago`, `currentDate`, `windowCount`, `unnestLateral`, `ascNullsLast`, `alwaysTrue`, `lateral`, `aliasColumn`, `minOf`, `maxOf`, `roundReal`, `multiply`, `scalarFromCte`) for use with `./db`.
|
|
30
30
|
- `./vite` — `buildIdAsset(fileName?)`: Vite plugin to emit the client `BUILD_ID` asset (from `__VINEXT_SHARED_BUILD_ID` or `__VINEXT_BUILD_ID`) during build in Vinext/Vite environments.
|
|
31
31
|
- `./errorHandling` — error reporting & stale deploy recovery barrel: `reportError`, `withErrorHandling`, `installConsoleErrorOverride`, `installGlobalErrorOverride`, `stringifyUnknown`, `formatErrorMessage`, `defaultIgnoredConsoleErrors`, `createServerErrorAction`, `isStaleDeployError`, `defaultStaleDeployPatterns`, `setStaleDeployPatterns`, `getStaleDeployPatterns`, `clearClientCache`, `useStaleDeployRecovery`, `shouldRecoverFromStaleDeploy`, `isRecentBuild`.
|
|
32
|
-
- `./isStaleDeployError` — `isStaleDeployError(error, patterns?)`, `setStaleDeployPatterns(patterns)`, `getStaleDeployPatterns()`: detector returning `true` for version skew / chunk load / hydration errors (ChunkLoadError, failed to fetch, loading CSS chunk, connection closed, RSC payload failure, minified error #412) with fast pre-lowercased pattern cache and intl-config integration (`errorHandling.staleDeployPatterns`).
|
|
32
|
+
- `./isStaleDeployError` — `isStaleDeployError(error, patterns?)`, `setStaleDeployPatterns(patterns)`, `getStaleDeployPatterns()`: detector returning `true` for version skew / chunk load / dynamic import / hydration errors (ChunkLoadError, failed to fetch, dynamically imported module failure, loading CSS chunk, connection closed, RSC payload failure, minified error #412, or missing stream error `undefined`) with fast pre-lowercased pattern cache and intl-config integration (`errorHandling.staleDeployPatterns`).
|
|
33
33
|
- `./clearClientCache` — `clearClientCache()`: async helper wiping `window.caches`, unregistering service workers, and clearing `sessionStorage` for recovering from stale deployments.
|
|
34
34
|
- `useStaleDeployRecovery(error, onRecover?, delayMs?)` (client hook, in `./errorHandling`) — once per build id (`localStorage['buildId']`, `sessionStorage` marker), waits `delayMs` (default 5000ms), runs optional `onRecover()` + `clearClientCache()` in parallel, then `window.location.reload()`. Returns whether a reload is pending, so caller renders a loading state instead of error UI. Recovers even past the one-reload cap when `localStorage['buildIdSetAt']` is <60s old (new deploy still settling). `shouldRecoverFromStaleDeploy(error, buildId, marker, recentBuild?)` and `isRecentBuild(setAt, now, windowMs?)` are the pure predicates.
|
|
35
35
|
- `./createServerErrorAction` — `createServerErrorAction(action, config)`: wrapper for server actions with standardized error reporting.
|