diff options
-rw-r--r-- | .changeset/chatty-ways-hunt.md | 5 | ||||
-rw-r--r-- | packages/astro/src/core/errors/dev/utils.ts | 19 | ||||
-rw-r--r-- | packages/astro/src/core/errors/dev/vite.ts | 15 | ||||
-rw-r--r-- | packages/astro/src/core/messages.ts | 7 |
4 files changed, 31 insertions, 15 deletions
diff --git a/.changeset/chatty-ways-hunt.md b/.changeset/chatty-ways-hunt.md new file mode 100644 index 000000000..d6a9584a1 --- /dev/null +++ b/.changeset/chatty-ways-hunt.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Adds a link to the error reference in the CLI when an error occurs diff --git a/packages/astro/src/core/errors/dev/utils.ts b/packages/astro/src/core/errors/dev/utils.ts index 69026b6cd..837b52fde 100644 --- a/packages/astro/src/core/errors/dev/utils.ts +++ b/packages/astro/src/core/errors/dev/utils.ts @@ -9,6 +9,7 @@ import { normalizePath } from 'vite'; import type { SSRError } from '../../../@types/astro.js'; import { removeLeadingForwardSlashWindows } from '../../path.js'; import { AggregateError, type ErrorWithMetadata } from '../errors.js'; +import { AstroErrorData } from '../index.js'; import { codeFrame } from '../printer.js'; import { normalizeLF } from '../utils.js'; @@ -206,13 +207,29 @@ function cleanErrorStack(stack: string) { .join('\n'); } +export function getDocsForError(err: ErrorWithMetadata): string | undefined { + if (err.name in AstroErrorData) { + return `https://docs.astro.build/en/reference/errors/${getKebabErrorName(err.name)}/`; + } + + return undefined; + + /** + * The docs has kebab-case urls for errors, so we need to convert the error name + * @param errorName + */ + function getKebabErrorName(errorName: string): string { + return errorName.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); + } +} + /** * Render a subset of Markdown to HTML or a CLI output */ export function renderErrorMarkdown(markdown: string, target: 'html' | 'cli') { const linkRegex = /\[(.+)\]\((.+)\)/gm; const boldRegex = /\*\*(.+)\*\*/gm; - const urlRegex = / (\b(https?|ftp):\/\/[-A-Z0-9+&@#\\/%?=~_|!:,.;]*[-A-Z0-9+&@#\\/%=~_|]) /gim; + const urlRegex = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\\/%?=~_|!:,.;]*[-A-Z0-9+&@#\\/%=~_|])/gim; const codeRegex = /`([^`]+)`/gim; if (target === 'html') { diff --git a/packages/astro/src/core/errors/dev/vite.ts b/packages/astro/src/core/errors/dev/vite.ts index 76ada2865..11e7cfe74 100644 --- a/packages/astro/src/core/errors/dev/vite.ts +++ b/packages/astro/src/core/errors/dev/vite.ts @@ -7,7 +7,7 @@ import { FailedToLoadModuleSSR, InvalidGlob, MdxIntegrationMissingError } from ' import { AstroError, type ErrorWithMetadata } from '../errors.js'; import { createSafeError } from '../utils.js'; import type { SSRLoadedRenderer } from './../../../@types/astro.js'; -import { renderErrorMarkdown } from './utils.js'; +import { getDocsForError, renderErrorMarkdown } from './utils.js'; export function enhanceViteSSRError({ error, @@ -137,10 +137,7 @@ export async function getViteErrorPayload(err: ErrorWithMetadata): Promise<Astro const message = renderErrorMarkdown(err.message.trim(), 'html'); const hint = err.hint ? renderErrorMarkdown(err.hint.trim(), 'html') : undefined; - const hasDocs = !!err.name; - const docslink = hasDocs - ? `https://docs.astro.build/en/reference/errors/${getKebabErrorName(err.name)}/` - : undefined; + const docslink = getDocsForError(err); const highlighter = await getHighlighter({ theme: 'css-variables' }); let highlighterLang = err.loc?.file?.split('.').pop(); @@ -178,12 +175,4 @@ export async function getViteErrorPayload(err: ErrorWithMetadata): Promise<Astro cause: err.cause, }, }; - - /** - * The docs has kebab-case urls for errors, so we need to convert the error name - * @param errorName - */ - function getKebabErrorName(errorName: string): string { - return errorName.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); - } } diff --git a/packages/astro/src/core/messages.ts b/packages/astro/src/core/messages.ts index dfa99c51d..d0c5a5e88 100644 --- a/packages/astro/src/core/messages.ts +++ b/packages/astro/src/core/messages.ts @@ -16,7 +16,7 @@ import { } from 'kleur/colors'; import type { ResolvedServerUrls } from 'vite'; import type { ZodError } from 'zod'; -import { renderErrorMarkdown } from './errors/dev/utils.js'; +import { getDocsForError, renderErrorMarkdown } from './errors/dev/utils.js'; import { AstroError, AstroUserError, @@ -216,6 +216,11 @@ export function formatErrorMessage(err: ErrorWithMetadata, args: string[] = []): yellow(padMultilineString(isOurError ? renderErrorMarkdown(err.hint, 'cli') : err.hint, 4)) ); } + const docsLink = getDocsForError(err); + if (docsLink) { + args.push(` ${bold('Error reference:')}`); + args.push(` ${underline(docsLink)}`); + } if (err.id || err.loc?.file) { args.push(` ${bold('File:')}`); args.push( |