From a54e520d3c139fa123e7029c5933951b5c7f5a39 Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Thu, 3 Oct 2024 19:55:55 +0100 Subject: [PATCH] fix: throw a useful error if rendering undefined entry (#12113) * fix: throw a useful error if rendering undefined entry * Update .changeset/wise-pumas-fry.md Co-authored-by: Sarah Rainsberger --------- Co-authored-by: Emanuele Stoppa Co-authored-by: Sarah Rainsberger --- .changeset/wise-pumas-fry.md | 5 +++++ packages/astro/src/content/runtime.ts | 6 +++++- packages/astro/src/core/errors/errors-data.ts | 11 +++++++++++ packages/astro/test/content-layer.test.js | 7 +++++++ .../fixtures/content-layer/src/pages/missing.astro | 14 ++++++++++++++ 5 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 .changeset/wise-pumas-fry.md create mode 100644 packages/astro/test/fixtures/content-layer/src/pages/missing.astro diff --git a/.changeset/wise-pumas-fry.md b/.changeset/wise-pumas-fry.md new file mode 100644 index 0000000000..90452298ca --- /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 bbe4a2b1f1..98d1c4fcdb 100644 --- a/packages/astro/src/content/runtime.ts +++ b/packages/astro/src/content/runtime.ts @@ -436,7 +436,11 @@ function updateImageReferencesInData>( 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 5760c5d967..42e8340055 100644 --- a/packages/astro/src/core/errors/errors-data.ts +++ b/packages/astro/src/core/errors/errors-data.ts @@ -1410,6 +1410,17 @@ export const UnknownContentCollectionError = { title: 'Unknown Content Collection Error.', } satisfies ErrorData; +/** + * @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 diff --git a/packages/astro/test/content-layer.test.js b/packages/astro/test/content-layer.test.js index 428a4ac3f2..78cde2bff2 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 0000000000..6fee7db07b --- /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) + +--- + +