diff options
-rw-r--r-- | .changeset/wise-pumas-fry.md | 5 | ||||
-rw-r--r-- | packages/astro/src/content/runtime.ts | 6 | ||||
-rw-r--r-- | packages/astro/src/core/errors/errors-data.ts | 11 | ||||
-rw-r--r-- | packages/astro/test/content-layer.test.js | 7 | ||||
-rw-r--r-- | packages/astro/test/fixtures/content-layer/src/pages/missing.astro | 14 |
5 files changed, 42 insertions, 1 deletions
diff --git a/.changeset/wise-pumas-fry.md b/.changeset/wise-pumas-fry.md new file mode 100644 index 000000000..90452298c --- /dev/null +++ b/.changeset/wise-pumas-fry.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Adds a helpful error when attempting to render an undefined collection entry diff --git a/packages/astro/src/content/runtime.ts b/packages/astro/src/content/runtime.ts index bbe4a2b1f..98d1c4fcd 100644 --- a/packages/astro/src/content/runtime.ts +++ b/packages/astro/src/content/runtime.ts @@ -436,7 +436,11 @@ function updateImageReferencesInData<T extends Record<string, unknown>>( export async function renderEntry( entry: DataEntry | { render: () => Promise<{ Content: AstroComponentFactory }> }, ) { - if (entry && 'render' in entry) { + if (!entry) { + throw new AstroError(AstroErrorData.RenderUndefinedEntryError); + } + + if ('render' in entry) { // This is an old content collection entry, so we use its render method return entry.render(); } diff --git a/packages/astro/src/core/errors/errors-data.ts b/packages/astro/src/core/errors/errors-data.ts index 5760c5d96..42e834005 100644 --- a/packages/astro/src/core/errors/errors-data.ts +++ b/packages/astro/src/core/errors/errors-data.ts @@ -1413,6 +1413,17 @@ export const UnknownContentCollectionError = { /** * @docs * @description + * Astro tried to render a content collection entry that was undefined. This can happen if you try to render an entry that does not exist. + */ +export const RenderUndefinedEntryError = { + name: 'RenderUndefinedEntryError', + title: 'Attempted to render an undefined content collection entry.', + hint: 'Check if the entry is undefined before passing it to `render()`', +} satisfies ErrorData; + +/** + * @docs + * @description * The `getDataEntryById` and `getEntryBySlug` functions are deprecated and cannot be used with content layer collections. Use the `getEntry` function instead. */ export const GetEntryDeprecationError = { diff --git a/packages/astro/test/content-layer.test.js b/packages/astro/test/content-layer.test.js index 428a4ac3f..78cde2bff 100644 --- a/packages/astro/test/content-layer.test.js +++ b/packages/astro/test/content-layer.test.js @@ -317,5 +317,12 @@ describe('Content Layer', () => { assert.ok(updated.fileLoader[0].data.temperament.includes('Bouncy')); await fixture.resetAllFiles(); }); + + it('returns an error if we render an undefined entry', async () => { + const res = await fixture.fetch('/missing'); + const text = await res.text(); + assert.equal(res.status, 500); + assert.ok(text.includes('RenderUndefinedEntryError')); + }); }); }); diff --git a/packages/astro/test/fixtures/content-layer/src/pages/missing.astro b/packages/astro/test/fixtures/content-layer/src/pages/missing.astro new file mode 100644 index 000000000..6fee7db07 --- /dev/null +++ b/packages/astro/test/fixtures/content-layer/src/pages/missing.astro @@ -0,0 +1,14 @@ +--- +import { getEntry, render } from "astro:content" +// Skipping the broken page in production so the build doesn't fail +if(import.meta.env.PROD) { + return new Response(null, { status: 404 }) +} + +const entry = await getEntry("spacecraft", "missing") + +const { Content } = await render(entry) + +--- + +<Content /> |