diff --git a/.changeset/hot-kiwis-shop.md b/.changeset/hot-kiwis-shop.md new file mode 100644 index 0000000000..e0faae6bfa --- /dev/null +++ b/.changeset/hot-kiwis-shop.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Show content config errors in overlay, instead of stopping the dev server. diff --git a/packages/astro/src/cli/sync/index.ts b/packages/astro/src/cli/sync/index.ts index 775bc8d689..f321b8b0ba 100644 --- a/packages/astro/src/cli/sync/index.ts +++ b/packages/astro/src/cli/sync/index.ts @@ -37,6 +37,12 @@ export async function sync( viteServer: tempViteServer, }); const typesResult = await contentTypesGenerator.init(); + + const contentConfig = globalContentConfigObserver.get(); + if (contentConfig.status === 'error') { + throw contentConfig.error; + } + if (typesResult.typesGenerated === false) { switch (typesResult.reason) { case 'no-content-dir': diff --git a/packages/astro/src/content/types-generator.ts b/packages/astro/src/content/types-generator.ts index 50f8088ded..e68634f2fc 100644 --- a/packages/astro/src/content/types-generator.ts +++ b/packages/astro/src/content/types-generator.ts @@ -5,6 +5,7 @@ import * as path from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; import { normalizePath, ViteDevServer } from 'vite'; import type { AstroSettings } from '../@types/astro.js'; +import { AstroError, AstroErrorData } from '../core/errors/index.js'; import { info, LogOptions, warn } from '../core/logger/core.js'; import { isRelativePath } from '../core/path.js'; import { CONTENT_TYPES_FILE } from './consts.js'; @@ -117,11 +118,19 @@ export async function createContentTypesGenerator({ } if (fileType === 'config') { contentConfigObserver.set({ status: 'loading' }); - const config = await loadContentConfig({ fs, settings, viteServer }); - if (config) { - contentConfigObserver.set({ status: 'loaded', config }); - } else { - contentConfigObserver.set({ status: 'error' }); + try { + const config = await loadContentConfig({ fs, settings, viteServer }); + if (config) { + contentConfigObserver.set({ status: 'loaded', config }); + } else { + contentConfigObserver.set({ status: 'does-not-exist' }); + } + } catch (e) { + contentConfigObserver.set({ + status: 'error', + error: + e instanceof Error ? e : new AstroError(AstroErrorData.UnknownContentCollectionError), + }); } return { shouldGenerateTypes: true }; diff --git a/packages/astro/src/content/utils.ts b/packages/astro/src/content/utils.ts index a1ddba7570..afde007433 100644 --- a/packages/astro/src/content/utils.ts +++ b/packages/astro/src/content/utils.ts @@ -275,8 +275,9 @@ export async function loadContentConfig({ type ContentCtx = | { status: 'init' } | { status: 'loading' } - | { status: 'error' } - | { status: 'loaded'; config: ContentConfig }; + | { status: 'does-not-exist' } + | { status: 'loaded'; config: ContentConfig } + | { status: 'error'; error: Error }; type Observable = { get: () => C; diff --git a/packages/astro/src/content/vite-plugin-content-imports.ts b/packages/astro/src/content/vite-plugin-content-imports.ts index 9621de0b4a..81dfd63357 100644 --- a/packages/astro/src/content/vite-plugin-content-imports.ts +++ b/packages/astro/src/content/vite-plugin-content-imports.ts @@ -46,6 +46,11 @@ export function astroContentImportPlugin({ message: 'Content config failed to load.', }); } + if (observable.status === 'error') { + // Throw here to bubble content config errors + // to the error overlay in development + throw observable.error; + } let contentConfig: ContentConfig | undefined = observable.status === 'loaded' ? observable.config : undefined;