feat(cli): Add docs error link to errors in the CLI (#8251)
This commit is contained in:
parent
ed39fbf168
commit
46c4c0e053
4 changed files with 31 additions and 15 deletions
5
.changeset/chatty-ways-hunt.md
Normal file
5
.changeset/chatty-ways-hunt.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Adds a link to the error reference in the CLI when an error occurs
|
|
@ -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') {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in a new issue