Log pretty error when MDX integration is missing (#5761)
* feat: add MDX integration error handling * chore: changeset * docs: applied -> installed Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
This commit is contained in:
parent
0a6b87236a
commit
fa8c131f88
4 changed files with 57 additions and 7 deletions
5
.changeset/smart-clouds-applaud.md
Normal file
5
.changeset/smart-clouds-applaud.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Add helpful error message when the MDX integration is missing.
|
|
@ -1,18 +1,29 @@
|
|||
import type { SSRLoadedRenderer } from './../../../@types/astro.js';
|
||||
import * as fs from 'fs';
|
||||
import { getHighlighter } from 'shiki';
|
||||
import { fileURLToPath } from 'url';
|
||||
import type { ErrorPayload } from 'vite';
|
||||
import type { ModuleLoader } from '../../module-loader/index.js';
|
||||
import { AstroErrorData } from '../errors-data.js';
|
||||
import type { ErrorWithMetadata } from '../errors.js';
|
||||
import { AstroError, ErrorWithMetadata } from '../errors.js';
|
||||
import { createSafeError } from '../utils.js';
|
||||
import { renderErrorMarkdown } from './utils.js';
|
||||
|
||||
export function enhanceViteSSRError(error: unknown, filePath?: URL, loader?: ModuleLoader): Error {
|
||||
export function enhanceViteSSRError({
|
||||
error,
|
||||
filePath,
|
||||
loader,
|
||||
renderers,
|
||||
}: {
|
||||
error: unknown;
|
||||
filePath?: URL;
|
||||
loader?: ModuleLoader;
|
||||
renderers?: SSRLoadedRenderer[];
|
||||
}): Error {
|
||||
// NOTE: We don't know where the error that's coming here comes from, so we need to be defensive regarding what we do
|
||||
// to it to make sure we keep as much information as possible. It's very possible that we receive an error that does not
|
||||
// follow any kind of standard formats (ex: a number, a string etc)
|
||||
const safeError = createSafeError(error) as ErrorWithMetadata;
|
||||
let safeError = createSafeError(error) as ErrorWithMetadata;
|
||||
|
||||
// Vite will give you better stacktraces, using sourcemaps.
|
||||
if (loader) {
|
||||
|
@ -48,6 +59,23 @@ export function enhanceViteSSRError(error: unknown, filePath?: URL, loader?: Mod
|
|||
}
|
||||
}
|
||||
|
||||
const fileId = safeError.id ?? safeError.loc?.file;
|
||||
|
||||
// Vite throws a syntax error trying to parse MDX without a plugin.
|
||||
// Suggest installing the MDX integration if none is found.
|
||||
if (
|
||||
!renderers?.find((r) => r.name === '@astrojs/mdx') &&
|
||||
safeError.message.match(/Syntax error/) &&
|
||||
fileId?.match(/\.mdx$/)
|
||||
) {
|
||||
safeError = new AstroError({
|
||||
...AstroErrorData.MdxIntegrationMissingError,
|
||||
message: AstroErrorData.MdxIntegrationMissingError.message(fileId),
|
||||
location: safeError.loc,
|
||||
stack: safeError.stack,
|
||||
}) as ErrorWithMetadata;
|
||||
}
|
||||
|
||||
// Since Astro.glob is a wrapper around Vite's import.meta.glob, errors don't show accurate information, let's fix that
|
||||
if (/Invalid glob/.test(safeError.message)) {
|
||||
const globPattern = safeError.message.match(/glob: "(.+)" \(/)?.[1];
|
||||
|
|
|
@ -534,6 +534,23 @@ See https://docs.astro.build/en/guides/server-side-rendering/ for more informati
|
|||
'A remark or rehype plugin attempted to inject invalid frontmatter. Ensure "astro.frontmatter" is set to a valid JSON object that is not `null` or `undefined`.',
|
||||
hint: 'See the frontmatter injection docs https://docs.astro.build/en/guides/markdown-content/#modifying-frontmatter-programmatically for more information.',
|
||||
},
|
||||
/**
|
||||
* @docs
|
||||
* @see
|
||||
* - [MDX installation and usage](https://docs.astro.build/en/guides/integrations-guide/mdx/)
|
||||
* @description
|
||||
* Unable to find the official `@astrojs/mdx` integration. This error is raised when using MDX files without an MDX integration installed.
|
||||
*/
|
||||
MdxIntegrationMissingError: {
|
||||
title: 'MDX integration missing.',
|
||||
code: 6004,
|
||||
message: (id: string) => {
|
||||
return `Unable to render ${JSON.stringify(
|
||||
id
|
||||
)}. Ensure that the \`@astrojs/mdx\` integration is installed.`;
|
||||
},
|
||||
hint: 'See the MDX integration docs for installation and usage instructions: https://docs.astro.build/en/guides/integrations-guide/mdx/',
|
||||
},
|
||||
// Config Errors - 7xxx
|
||||
UnknownConfigError: {
|
||||
title: 'Unknown configuration error.',
|
||||
|
|
|
@ -59,13 +59,13 @@ export async function preload({
|
|||
// Load the module from the Vite SSR Runtime.
|
||||
const mod = (await env.loader.import(fileURLToPath(filePath))) as ComponentInstance;
|
||||
return [renderers, mod];
|
||||
} catch (err) {
|
||||
} catch (error) {
|
||||
// If the error came from Markdown or CSS, we already handled it and there's no need to enhance it
|
||||
if (MarkdownError.is(err) || CSSError.is(err) || AggregateError.is(err)) {
|
||||
throw err;
|
||||
if (MarkdownError.is(error) || CSSError.is(error) || AggregateError.is(error)) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
throw enhanceViteSSRError(err as Error, filePath, env.loader);
|
||||
throw enhanceViteSSRError({ error, filePath, loader: env.loader, renderers });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue