diff --git a/packages/void/src/cli/deploy-managed-full.ts b/packages/void/src/cli/deploy-managed-full.ts index c6aad32ce..73d659c8a 100644 --- a/packages/void/src/cli/deploy-managed-full.ts +++ b/packages/void/src/cli/deploy-managed-full.ts @@ -9,8 +9,8 @@ import { } from '../asset-routing.ts'; import { type VoidConfig, isNodeTarget } from '../config.ts'; import { collectRevalidate } from '../isr-config.ts'; -import { voidWarn } from '../log.ts'; import { type DetectedFramework } from '../plugin-inference.ts'; +import { assertNoPrerenderFailures } from '../prerender-render.ts'; import { collectPrerenderPaths, collectPrerenderPathsNode, @@ -164,8 +164,8 @@ export async function runFullDeploy( if (result.paths.length === 0) { log.info('No pages to prerender'); - } else if (result.failed.length > 0) { - voidWarn(`${formatCount(result.failed.length, 'page')} failed to prerender`); + } else { + assertNoPrerenderFailures(result.failed); } } diff --git a/packages/void/src/plugin-prerender.ts b/packages/void/src/plugin-prerender.ts index dba2da003..5b9b9ef8e 100644 --- a/packages/void/src/plugin-prerender.ts +++ b/packages/void/src/plugin-prerender.ts @@ -2,7 +2,8 @@ import { join } from 'pathslash'; import type { Plugin } from 'vite'; import { resolveDistDir, resolveWorkerDirName } from './cli/build-output-dir.ts'; import { isNodeTarget, type VoidConfig } from './config.ts'; -import { voidLog, voidWarn, setShowTimestamp } from './log.ts'; +import { voidLog, setShowTimestamp } from './log.ts'; +import { assertNoPrerenderFailures } from './prerender-render.ts'; import { prerenderPages, prerenderPagesNode } from './prerender.ts'; import { resolveRemoteMode } from './shared/env.ts'; @@ -64,9 +65,7 @@ export function prerenderPlugin(root: string, config: VoidConfig): Plugin { return; } - if (result.failed.length > 0) { - voidWarn(`${result.failed.length} page(s) failed to prerender`); - } + assertNoPrerenderFailures(result.failed); }, }; } diff --git a/packages/void/src/prerender-render.ts b/packages/void/src/prerender-render.ts index 7e2e3b248..89ea6267b 100644 --- a/packages/void/src/prerender-render.ts +++ b/packages/void/src/prerender-render.ts @@ -9,6 +9,14 @@ export type PrerenderResult = { failed: Array<{ path: string; error: string }>; }; +export function assertNoPrerenderFailures(failed: PrerenderResult['failed']): void { + if (failed.length === 0) { + return; + } + const details = failed.map(({ path, error }) => ` ${path}: ${error}`).join('\n'); + throw new Error(`${failed.length} page(s) failed to prerender:\n${details}`); +} + export function outputFileForPath(path: string): string { return path === '/' ? 'index.html' : `${path.slice(1)}.html`; } diff --git a/packages/void/test/unit/prerender-render.test.ts b/packages/void/test/unit/prerender-render.test.ts index 5d9ee0a92..b0e0790dc 100644 --- a/packages/void/test/unit/prerender-render.test.ts +++ b/packages/void/test/unit/prerender-render.test.ts @@ -3,7 +3,10 @@ import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { afterEach, describe, expect, it } from 'vite-plus/test'; import { serializePageData } from '../../src/pages/serialize.ts'; -import { renderPrerenderPaths } from '../../src/prerender-render.ts'; +import { + assertNoPrerenderFailures, + renderPrerenderPaths, +} from '../../src/prerender-render.ts'; import { createAssetFallback } from '../../src/runtime/routing-worker.ts'; const roots: Array = []; @@ -199,3 +202,15 @@ describe('prerender pool', () => { }); }); }); + +describe('assertNoPrerenderFailures', () => { + it('does nothing when there are no failures', () => { + expect(() => assertNoPrerenderFailures([])).not.toThrow(); + }); + + it('throws with path details when prerender failed', () => { + expect(() => + assertNoPrerenderFailures([{ path: '/throws', error: 'HTTP 500' }]), + ).toThrow('1 page(s) failed to prerender:\n /throws: HTTP 500'); + }); +});