Skip to content

Commit 533d2b8

Browse files
yakanetdummdidummeltigerchinobenmccannRich-Harris
authored
feat: configure error reporting for prerendered routes (#11702)
* feat: configure error reporting when routes marked as prerendable were not prerendered * tweak wording, update links * lint * lint * Update packages/kit/src/exports/public.d.ts Co-authored-by: Ben McCann <[email protected]> * Update packages/kit/types/index.d.ts * Update packages/kit/types/index.d.ts * Update packages/kit/src/exports/public.d.ts * rename to handleUnseenRoutes * tweak message --------- Co-authored-by: Simon H <[email protected]> Co-authored-by: Tee Ming <[email protected]> Co-authored-by: Ben McCann <[email protected]> Co-authored-by: Rich Harris <[email protected]>
1 parent 9f82941 commit 533d2b8

File tree

6 files changed

+78
-5
lines changed

6 files changed

+78
-5
lines changed

.changeset/gentle-llamas-yawn.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@sveltejs/kit": minor
3+
---
4+
5+
feat: configure error reporting when routes marked as prerendable were not prerendered

packages/kit/src/core/config/options.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,20 @@ const options = object(
251251
}
252252
),
253253

254+
handleUnseenRoutes: validate(
255+
(/** @type {any} */ { message }) => {
256+
throw new Error(
257+
message +
258+
'\nTo suppress or handle this error, implement `handleUnseenRoutes` in https://svelte.dev/docs/kit/configuration#prerender'
259+
);
260+
},
261+
(input, keypath) => {
262+
if (typeof input === 'function') return input;
263+
if (['fail', 'warn', 'ignore'].includes(input)) return input;
264+
throw new Error(`${keypath} should be "fail", "warn", "ignore" or a custom function`);
265+
}
266+
),
267+
254268
origin: validate('http://sveltekit-prerender', (input, keypath) => {
255269
assert_string(input, keypath);
256270

packages/kit/src/core/postbuild/prerender.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,15 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env }) {
160160
}
161161
);
162162

163+
const handle_not_prerendered_route = normalise_error_handler(
164+
log,
165+
config.prerender.handleUnseenRoutes,
166+
({ routes }) => {
167+
const list = routes.map((id) => ` - ${id}`).join('\n');
168+
return `The following routes were marked as prerenderable, but were not prerendered because they were not found while crawling your app:\n${list}\n\nSee the \`handleUnseenRoutes\` option in https://svelte.dev/docs/kit/configuration#prerender for more info.`;
169+
}
170+
);
171+
163172
const q = queue(config.prerender.concurrency);
164173

165174
/**
@@ -562,11 +571,7 @@ async function prerender({ hash, out, manifest_path, metadata, verbose, env }) {
562571
}
563572

564573
if (not_prerendered.length > 0) {
565-
const list = not_prerendered.map((id) => ` - ${id}`).join('\n');
566-
567-
throw new Error(
568-
`The following routes were marked as prerenderable, but were not prerendered because they were not found while crawling your app:\n${list}\n\nSee https://svelte.dev/docs/kit/page-options#prerender-troubleshooting for info on how to solve this`
569-
);
574+
handle_not_prerendered_route({ routes: not_prerendered });
570575
}
571576

572577
return { prerendered, prerender_map };

packages/kit/src/exports/public.d.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
PrerenderEntryGeneratorMismatchHandlerValue,
1313
PrerenderHttpErrorHandlerValue,
1414
PrerenderMissingIdHandlerValue,
15+
PrerenderMissingRoutesHandlerValue,
1516
PrerenderOption,
1617
RequestOptions,
1718
RouteSegment
@@ -740,6 +741,21 @@ export interface KitConfig {
740741
* @since 1.16.0
741742
*/
742743
handleEntryGeneratorMismatch?: PrerenderEntryGeneratorMismatchHandlerValue;
744+
/**
745+
* How to respond when a route is marked as prerenderable but has not been prerendered.
746+
*
747+
* - `'fail'` — fail the build
748+
* - `'ignore'` - silently ignore the failure and continue
749+
* - `'warn'` — continue, but print a warning
750+
* - `(details) => void` — a custom error handler that takes a `details` object with a `routes` property which contains all routes that haven't been prerendered. If you `throw` from this function, the build will fail
751+
*
752+
* The default behavior is to fail the build. This may be undesirable when you know that some of your routes may never be reached under certain
753+
* circumstances such as a CMS not returning data for a specific area, resulting in certain routes never being reached.
754+
*
755+
* @default "fail"
756+
* @since 2.16.0
757+
*/
758+
handleUnseenRoutes?: PrerenderMissingRoutesHandlerValue;
743759
/**
744760
* The value of `url.origin` during prerendering; useful if it is included in rendered content.
745761
* @default "http://sveltekit-prerender"

packages/kit/src/types/private.d.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,17 @@ export interface PrerenderEntryGeneratorMismatchHandler {
208208
(details: { generatedFromId: string; entry: string; matchedId: string; message: string }): void;
209209
}
210210

211+
export interface PrerenderEntryMissingRoutesHandler {
212+
(details: { routes: string[]; message: string }): void;
213+
}
214+
211215
export type PrerenderHttpErrorHandlerValue = 'fail' | 'warn' | 'ignore' | PrerenderHttpErrorHandler;
212216
export type PrerenderMissingIdHandlerValue = 'fail' | 'warn' | 'ignore' | PrerenderMissingIdHandler;
217+
export type PrerenderMissingRoutesHandlerValue =
218+
| 'fail'
219+
| 'warn'
220+
| 'ignore'
221+
| PrerenderEntryMissingRoutesHandler;
213222
export type PrerenderEntryGeneratorMismatchHandlerValue =
214223
| 'fail'
215224
| 'warn'

packages/kit/types/index.d.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,21 @@ declare module '@sveltejs/kit' {
717717
* @since 1.16.0
718718
*/
719719
handleEntryGeneratorMismatch?: PrerenderEntryGeneratorMismatchHandlerValue;
720+
/**
721+
* How to respond when a route is marked as prerenderable but has not been prerendered.
722+
*
723+
* - `'fail'` — fail the build
724+
* - `'ignore'` - silently ignore the failure and continue
725+
* - `'warn'` — continue, but print a warning
726+
* - `(details) => void` — a custom error handler that takes a `details` object with a `routes` property which contains all routes that haven't been prerendered. If you `throw` from this function, the build will fail
727+
*
728+
* The default behavior is to fail the build. This may be undesirable when you know that some of your routes may never be reached under certain
729+
* circumstances such as a CMS not returning data for a specific area, resulting in certain routes never being reached.
730+
*
731+
* @default "fail"
732+
* @since 2.16.0
733+
*/
734+
handleUnseenRoutes?: PrerenderMissingRoutesHandlerValue;
720735
/**
721736
* The value of `url.origin` during prerendering; useful if it is included in rendered content.
722737
* @default "http://sveltekit-prerender"
@@ -1996,8 +2011,17 @@ declare module '@sveltejs/kit' {
19962011
(details: { generatedFromId: string; entry: string; matchedId: string; message: string }): void;
19972012
}
19982013

2014+
interface PrerenderEntryMissingRoutesHandler {
2015+
(details: { routes: string[]; message: string }): void;
2016+
}
2017+
19992018
type PrerenderHttpErrorHandlerValue = 'fail' | 'warn' | 'ignore' | PrerenderHttpErrorHandler;
20002019
type PrerenderMissingIdHandlerValue = 'fail' | 'warn' | 'ignore' | PrerenderMissingIdHandler;
2020+
type PrerenderMissingRoutesHandlerValue =
2021+
| 'fail'
2022+
| 'warn'
2023+
| 'ignore'
2024+
| PrerenderEntryMissingRoutesHandler;
20012025
type PrerenderEntryGeneratorMismatchHandlerValue =
20022026
| 'fail'
20032027
| 'warn'

0 commit comments

Comments
 (0)