From af3c5a2e25bd3e7b2a3f7f08e41ee457093c8cb1 Mon Sep 17 00:00:00 2001 From: Bjorn Lu Date: Mon, 29 May 2023 20:42:31 +0800 Subject: [PATCH] Use AstroError for Astro.glob errors (#7219) Co-authored-by: Erika <3019731+Princesseuh@users.noreply.github.com> Co-authored-by: sarah11918 --- .changeset/strange-socks-give.md | 5 ++++ packages/astro/e2e/errors.test.js | 23 ++++++++++++-- .../src/components/AstroGlobOutsideAstro.js | 3 ++ .../src/pages/astro-glob-no-match.astro | 3 ++ .../src/pages/astro-glob-outside-astro.astro | 5 ++++ packages/astro/e2e/test-utils.js | 2 ++ packages/astro/src/core/errors/errors-data.ts | 30 +++++++++++++++++++ .../astro/src/runtime/server/astro-global.ts | 13 +++++--- .../test/units/runtime/astro-global.test.js | 11 +++++-- 9 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 .changeset/strange-socks-give.md create mode 100644 packages/astro/e2e/fixtures/errors/src/components/AstroGlobOutsideAstro.js create mode 100644 packages/astro/e2e/fixtures/errors/src/pages/astro-glob-no-match.astro create mode 100644 packages/astro/e2e/fixtures/errors/src/pages/astro-glob-outside-astro.astro diff --git a/.changeset/strange-socks-give.md b/.changeset/strange-socks-give.md new file mode 100644 index 000000000000..f1e9492bd75e --- /dev/null +++ b/.changeset/strange-socks-give.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Use `AstroError` for `Astro.glob` errors diff --git a/packages/astro/e2e/errors.test.js b/packages/astro/e2e/errors.test.js index 35599ce97109..2055f1cdf0d7 100644 --- a/packages/astro/e2e/errors.test.js +++ b/packages/astro/e2e/errors.test.js @@ -1,14 +1,21 @@ import { expect } from '@playwright/test'; -import { getErrorOverlayContent, testFactory } from './test-utils.js'; +import { getErrorOverlayContent, silentLogging, testFactory } from './test-utils.js'; const test = testFactory({ root: './fixtures/errors/', + // Only test the error overlay, don't print to console + vite: { + logLevel: 'silent', + }, }); let devServer; test.beforeAll(async ({ astro }) => { - devServer = await astro.startDevServer(); + devServer = await astro.startDevServer({ + // Only test the error overlay, don't print to console + logging: silentLogging, + }); }); test.afterAll(async ({ astro }) => { @@ -89,4 +96,16 @@ test.describe('Error display', () => { expect(await page.locator('vite-error-overlay').count()).toEqual(0); }); + + test('astro glob no match error', async ({ page, astro }) => { + await page.goto(astro.resolveUrl('/astro-glob-no-match'), { waitUntil: 'networkidle' }); + const message = (await getErrorOverlayContent(page)).message; + expect(message).toMatch('did not return any matching files'); + }); + + test('astro glob used outside of an astro file', async ({ page, astro }) => { + await page.goto(astro.resolveUrl('/astro-glob-outside-astro'), { waitUntil: 'networkidle' }); + const message = (await getErrorOverlayContent(page)).message; + expect(message).toMatch('can only be used in'); + }); }); diff --git a/packages/astro/e2e/fixtures/errors/src/components/AstroGlobOutsideAstro.js b/packages/astro/e2e/fixtures/errors/src/components/AstroGlobOutsideAstro.js new file mode 100644 index 000000000000..5307474c035a --- /dev/null +++ b/packages/astro/e2e/fixtures/errors/src/components/AstroGlobOutsideAstro.js @@ -0,0 +1,3 @@ +export function globSomething(Astro) { + return Astro.glob('./*.lua') +} diff --git a/packages/astro/e2e/fixtures/errors/src/pages/astro-glob-no-match.astro b/packages/astro/e2e/fixtures/errors/src/pages/astro-glob-no-match.astro new file mode 100644 index 000000000000..a7739af5807f --- /dev/null +++ b/packages/astro/e2e/fixtures/errors/src/pages/astro-glob-no-match.astro @@ -0,0 +1,3 @@ +--- +Astro.glob('./*.lua') +--- \ No newline at end of file diff --git a/packages/astro/e2e/fixtures/errors/src/pages/astro-glob-outside-astro.astro b/packages/astro/e2e/fixtures/errors/src/pages/astro-glob-outside-astro.astro new file mode 100644 index 000000000000..328de56ecf25 --- /dev/null +++ b/packages/astro/e2e/fixtures/errors/src/pages/astro-glob-outside-astro.astro @@ -0,0 +1,5 @@ +--- +import { globSomething } from '../components/AstroGlobOutsideAstro' + +globSomething(Astro) +--- \ No newline at end of file diff --git a/packages/astro/e2e/test-utils.js b/packages/astro/e2e/test-utils.js index d025527d6e91..72c6e8d5685f 100644 --- a/packages/astro/e2e/test-utils.js +++ b/packages/astro/e2e/test-utils.js @@ -5,6 +5,8 @@ import { loadFixture as baseLoadFixture } from '../test/test-utils.js'; export const isWindows = process.platform === 'win32'; +export { silentLogging } from '../test/test-utils.js'; + // Get all test files in directory, assign unique port for each of them so they don't conflict const testFiles = await fs.readdir(new URL('.', import.meta.url)); const testFileToPort = new Map(); diff --git a/packages/astro/src/core/errors/errors-data.ts b/packages/astro/src/core/errors/errors-data.ts index e50000c5651f..49ada2a1927d 100644 --- a/packages/astro/src/core/errors/errors-data.ts +++ b/packages/astro/src/core/errors/errors-data.ts @@ -719,6 +719,36 @@ See https://docs.astro.build/en/guides/server-side-rendering/ for more informati message: (imageFilePath: string) => `\`Image\`'s and \`getImage\`'s \`src\` parameter must be an imported image or an URL, it cannot be a filepath. Received \`${imageFilePath}\`.`, }, + + /** + * @docs + * @see + * - [Astro.glob](https://docs.astro.build/en/reference/api-reference/#astroglob) + * @description + * `Astro.glob()` can only be used in `.astro` files. You can use [`import.meta.glob()`](https://vitejs.dev/guide/features.html#glob-import) instead to acheive the same result. + */ + AstroGlobUsedOutside: { + title: 'Astro.glob() used outside of an Astro file.', + code: 3035, + message: (globStr: string) => + `\`Astro.glob(${globStr})\` can only be used in \`.astro\` files. \`import.meta.glob(${globStr})\` can be used instead to achieve a similar result.`, + hint: "See Vite's documentation on `import.meta.glob` for more information: https://vitejs.dev/guide/features.html#glob-import", + }, + + /** + * @docs + * @see + * - [Astro.glob](https://docs.astro.build/en/reference/api-reference/#astroglob) + * @description + * `Astro.glob()` did not return any matching files. There might be a typo in the glob pattern. + */ + AstroGlobNoMatch: { + title: 'Astro.glob() did not match any files.', + code: 3036, + message: (globStr: string) => + `\`Astro.glob(${globStr})\` did not return any matching files. Check the pattern for typos.`, + }, + // No headings here, that way Vite errors are merged with Astro ones in the docs, which makes more sense to users. // Vite Errors - 4xxx /** diff --git a/packages/astro/src/runtime/server/astro-global.ts b/packages/astro/src/runtime/server/astro-global.ts index 70c4e565b41e..da1f0e78488a 100644 --- a/packages/astro/src/runtime/server/astro-global.ts +++ b/packages/astro/src/runtime/server/astro-global.ts @@ -1,17 +1,22 @@ import type { AstroGlobalPartial } from '../../@types/astro'; import { ASTRO_VERSION } from '../../core/constants.js'; +import { AstroError, AstroErrorData } from '../../core/errors/index.js'; /** Create the Astro.glob() runtime function. */ function createAstroGlobFn() { const globHandler = (importMetaGlobResult: Record, globValue: () => any) => { if (typeof importMetaGlobResult === 'string') { - throw new Error( - 'Astro.glob() does not work outside of an Astro file. Use `import.meta.glob()` instead.' - ); + throw new AstroError({ + ...AstroErrorData.AstroGlobUsedOutside, + message: AstroErrorData.AstroGlobUsedOutside.message(JSON.stringify(importMetaGlobResult)), + }); } let allEntries = [...Object.values(importMetaGlobResult)]; if (allEntries.length === 0) { - throw new Error(`Astro.glob(${JSON.stringify(globValue())}) - no matches found.`); + throw new AstroError({ + ...AstroErrorData.AstroGlobNoMatch, + message: AstroErrorData.AstroGlobNoMatch.message(JSON.stringify(importMetaGlobResult)), + }); } // Map over the `import()` promises, calling to load them. return Promise.all(allEntries.map((fn) => fn())); diff --git a/packages/astro/test/units/runtime/astro-global.test.js b/packages/astro/test/units/runtime/astro-global.test.js index 975651b76687..59585de3956c 100644 --- a/packages/astro/test/units/runtime/astro-global.test.js +++ b/packages/astro/test/units/runtime/astro-global.test.js @@ -6,8 +6,13 @@ describe('astro global', () => { const Astro = createAstro(undefined); expect(() => { Astro.glob('./**/*.md'); - }).to.throw( - 'Astro.glob() does not work outside of an Astro file. Use `import.meta.glob()` instead.' - ); + }).to.throw(/can only be used in/); + }); + + it('Glob should error if has no results', async () => { + const Astro = createAstro(undefined); + expect(() => { + Astro.glob([], () => './**/*.md'); + }).to.throw(/did not return any matching files/); }); });