diff --git a/.changeset/shy-toys-confess.md b/.changeset/shy-toys-confess.md new file mode 100644 index 000000000000..cd7a877cb0a2 --- /dev/null +++ b/.changeset/shy-toys-confess.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +More robust manifest error recovery diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index d175a9cc14aa..3c4fb3e5c651 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -36,6 +36,9 @@ export async function dev(vite, vite_config, svelte_config) { /** @type {import('types').SSRManifest} */ let manifest; + /** @type {Error | null} */ + let manifest_error = null; + /** @param {string} id */ async function resolve(id) { const url = id.startsWith('..') ? `/@fs${path.posix.resolve(id)}` : `/${id}`; @@ -51,18 +54,24 @@ export async function dev(vite, vite_config, svelte_config) { async function update_manifest() { try { ({ manifest_data } = await sync.create(svelte_config)); + + if (manifest_error) { + manifest_error = null; + vite.ws.send({ type: 'full-reload' }); + } } catch (error) { - console.error(colors.bold().red('Failed to update manifest')); + manifest_error = /** @type {Error} */ (error); + + console.error(colors.bold().red('Invalid routes')); console.error(error); vite.ws.send({ type: 'error', err: { - message: `Failed to udpate manifest: ${ - /** @type {Error} */ (error)?.message ?? 'Unknown error' - }`, - stack: /** @type {Error} */ (error)?.stack ?? '' + message: manifest_error.message ?? 'Invalid routes', + stack: '' } }); + return; } @@ -447,6 +456,27 @@ export async function dev(vite, vite_config, svelte_config) { const template = load_template(cwd, svelte_config); const error_page = load_error_page(svelte_config); + /** @param {{ status: number; message: string }} opts */ + const error_template = ({ status, message }) => { + return error_page + .replace(/%sveltekit\.status%/g, String(status)) + .replace(/%sveltekit\.error\.message%/g, message); + }; + + if (manifest_error) { + console.error(colors.bold().red('Invalid routes')); + console.error(manifest_error); + + res.writeHead(500, { + 'Content-Type': 'text/html; charset=utf-8' + }); + res.end( + error_template({ status: 500, message: manifest_error.message ?? 'Invalid routes' }) + ); + + return; + } + const rendered = await respond( request, { @@ -501,11 +531,7 @@ export async function dev(vite, vite_config, svelte_config) { ); }, app_template_contains_nonce: template.includes('%sveltekit.nonce%'), - error_template: ({ status, message }) => { - return error_page - .replace(/%sveltekit\.status%/g, String(status)) - .replace(/%sveltekit\.error\.message%/g, message); - }, + error_template, service_worker: svelte_config.kit.serviceWorker.register && !!resolve_entry(svelte_config.kit.files.serviceWorker),