Skip to content

Commit

Permalink
Change config prerender.force to prerender.onError
Browse files Browse the repository at this point in the history
fixes sveltejs#1940

- Changing from `force` to `onError` gives a somewhat more descriptive
  name to the option.
- Using the strings "fail" and "continue" further clarifies what the
  option does.
- Providing your own function to deal with an error allows for
  fine-tuning which errors fail the build and which do not.

The original ticket suggested that the custom function return a boolean,
but after seeing the implementation of the error handler in svelteKit, I
thought it more fitting to just allow it the exact same API: throw if
you want the build to fail.
  • Loading branch information
happycollision committed Jul 25, 2021
1 parent 68c3906 commit cec2479
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 14 deletions.
5 changes: 5 additions & 0 deletions .changeset/tame-guests-collect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

Remove the `prerender.force` option in favor of `prerender.onError`
25 changes: 23 additions & 2 deletions documentation/docs/14-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const config = {
prerender: {
crawl: true,
enabled: true,
force: false,
onError: 'fail',
pages: ['*']
},
router: true,
Expand Down Expand Up @@ -148,7 +148,28 @@ See [Prerendering](#ssr-and-javascript-prerender). An object containing zero or

- `crawl` — determines whether SvelteKit should find pages to prerender by following links from the seed page(s)
- `enabled` — set to `false` to disable prerendering altogether
- `force` — if `true`, a page that fails to render will _not_ cause the entire build to fail
- `onError`

- `"fail"` — (default) fails the build when a routing error is encountered when following a link
- `"continue"` — allows the build to continue, despite routing errors
- function — you can use the `errorDetails` to determine whether or not to `throw`, thereby failing the build.

```ts
// The function receives this object
type ErrorDetails = {
status: number;
path: string;
parent: string | null;
verb: string;
};

// Example custom function
function handleError({ status, path, parent, verb }: ErrorDetails) {
if (path.startsWith('/blog')) throw new Error('Missing a blog page!');
console.warn(`${status} ${path}${parent ? ` (${verb} from ${parent})` : ''}`);
}
```

- `pages`an array of pages to prerender, or start crawling from (if `crawl: true`). The `*` string includes all non-dynamic routes (i.e. pages with no `[parameters]` )

### router
Expand Down
28 changes: 21 additions & 7 deletions packages/kit/src/core/adapt/prerender.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,27 @@ export async function prerender({ cwd, out, log, config, build_data, fallback, a
});

/** @type {(status: number, path: string, parent: string | null, verb: string) => void} */
const error = config.kit.prerender.force
? (status, path, parent, verb) => {
log.error(`${status} ${path}${parent ? ` (${verb} from ${parent})` : ''}`);
}
: (status, path, parent, verb) => {
throw new Error(`${status} ${path}${parent ? ` (${verb} from ${parent})` : ''}`);
};
const error = (function () {
const { onError } = config.kit.prerender;
/** @type {(details: import('types/config').RequestDetails ) => string} */
const detailsToString = ({ status, path, parent, verb }) =>
`${status} ${path}${parent ? ` (${verb} from ${parent})` : ''}`;
switch (onError) {
case 'continue':
/** @type {(status: number, path: string, parent: string | null, verb: string) => void} */
return (status, path, parent, verb) => {
log.error(detailsToString({ status, path, parent, verb }));
};
case 'fail':
/** @type {(status: number, path: string, parent: string | null, verb: string) => never} */
return (status, path, parent, verb) => {
throw new Error(detailsToString({ status, path, parent, verb }));
};
default:
/** @type {(status: number, path: string, parent: string | null, verb: string) => void|never} */
return (status, path, parent, verb) => onError({ status, path, parent, verb });
}
})();

const files = new Set([...build_data.static, ...build_data.client]);

Expand Down
4 changes: 2 additions & 2 deletions packages/kit/src/core/config/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ test('fills in defaults', () => {
prerender: {
crawl: true,
enabled: true,
force: false,
onError: 'fail',
pages: ['*']
},
router: true,
Expand Down Expand Up @@ -150,7 +150,7 @@ test('fills in partial blanks', () => {
prerender: {
crawl: true,
enabled: true,
force: false,
onError: 'fail',
pages: ['*']
},
router: true,
Expand Down
14 changes: 13 additions & 1 deletion packages/kit/src/core/config/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,19 @@ const options = {
children: {
crawl: expect_boolean(true),
enabled: expect_boolean(true),
force: expect_boolean(false),
onError: {
type: 'leaf',
default: 'fail',
validate: (option, keypath) => {
if (typeof option === 'function') return option;
if (!['continue', 'fail'].includes(option)) {
throw new Error(
`${keypath} should be either a custom function or one of "continue" or "fail"`
);
}
return option;
}
},
pages: {
type: 'leaf',
default: ['*'],
Expand Down
2 changes: 1 addition & 1 deletion packages/kit/src/core/config/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ async function testLoadDefaultConfig(path) {
exclude: []
},
paths: { base: '', assets: '/.' },
prerender: { crawl: true, enabled: true, force: false, pages: ['*'] },
prerender: { crawl: true, enabled: true, onError: 'fail', pages: ['*'] },
router: true,
ssr: true,
target: null,
Expand Down
9 changes: 8 additions & 1 deletion packages/kit/types/config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ export type Config = {
preprocess?: any;
};

export type RequestDetails = {
status: number;
path: string;
parent: string | null;
verb: string;
};

export type ValidatedConfig = {
compilerOptions: any;
extensions: string[];
Expand Down Expand Up @@ -117,7 +124,7 @@ export type ValidatedConfig = {
prerender: {
crawl: boolean;
enabled: boolean;
force: boolean;
onError: 'fail' | 'continue' | ((details: RequestDetails) => void | never);
pages: string[];
};
router: boolean;
Expand Down

0 comments on commit cec2479

Please sign in to comment.