Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: show file name with invalid frontmatter errors for MDX #12355

Merged
merged 7 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/wise-bulldogs-jump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Improves error reporting for invalid frontmatter in MDX files during the `astro build` command. The error message now includes the file path where the frontmatter parsing failed.
4 changes: 2 additions & 2 deletions packages/astro/src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ async function runCommand(cmd: string, flags: yargs.Arguments) {
}
case 'sync': {
const { sync } = await import('./sync/index.js');
const exitCode = await sync({ flags });
return process.exit(exitCode);
await sync({ flags });
return;
Comment on lines +136 to +137
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have a global handler for CLI that handles more stuff (telemetry, error formatting etc) so this wasn't really useful.

}
case 'preferences': {
const { preferences } = await import('./preferences/index.js');
Expand Down
7 changes: 1 addition & 6 deletions packages/astro/src/cli/sync/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,5 @@ export async function sync({ flags }: SyncOptions) {
return 0;
}

try {
await _sync(flagsToAstroInlineConfig(flags), { telemetry: true });
return 0;
} catch (_) {
return 1;
}
await _sync(flagsToAstroInlineConfig(flags), { telemetry: true });
}
2 changes: 1 addition & 1 deletion packages/astro/src/core/errors/errors-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1388,7 +1388,7 @@ export const GenerateContentTypesError = {
title: 'Failed to generate content types.',
message: (errorMessage: string) =>
`\`astro sync\` command failed to generate content collection types: ${errorMessage}`,
hint: 'Check your `src/content/config.*` file for typos.',
hint: 'This error is often caused by a syntax error inside your content, or your content configuration file. Check your `src/content/config.*` file for typos.',
} satisfies ErrorData;
/**
* @docs
Expand Down
5 changes: 5 additions & 0 deletions packages/astro/src/core/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,11 @@ export function formatErrorMessage(err: ErrorWithMetadata, showFullStacktrace: b
output.push(` ${cyan(underline(docsLink))}`);
}

if (showFullStacktrace && err.loc) {
output.push(` ${bold('Location:')}`);
output.push(` ${underline(`${err.loc.file}:${err.loc.line ?? 0}:${err.loc.column ?? 0}`)}`);
}
Comment on lines +301 to +304
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was something removed by Fred's previous pass on errors making them shorter 😃

I added it back, but only when the full stack trace is shown (which is either in debug in dev, or on full crashes in the CLI), so it should be shown in only contexts where it's not available elsewhere.


if (err.stack) {
output.push(` ${bold('Stack trace:')}`);
output.push(dim(formatErrorStackTrace(err, showFullStacktrace)));
Expand Down
90 changes: 36 additions & 54 deletions packages/astro/src/core/sync/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
AstroError,
AstroErrorData,
AstroUserError,
type ErrorWithMetadata,
createSafeError,
isAstroError,
} from '../errors/index.js';
Expand Down Expand Up @@ -62,17 +63,7 @@ export default async function sync(
logger,
});

// Run `astro:config:done`
// Actions will throw if there is misconfiguration, so catch here.
try {
await runHookConfigDone({ settings, logger });
} catch (err) {
if (err instanceof Error) {
const errorMessage = err.toString();
logger.error('sync', errorMessage);
}
throw err;
}
await runHookConfigDone({ settings, logger });

return await syncInternal({ settings, logger, fs, force: inlineConfig.force });
}
Expand Down Expand Up @@ -112,51 +103,41 @@ export async function syncInternal({

const timerStart = performance.now();

try {
if (!skip?.content) {
await syncContentCollections(settings, { fs, logger });
settings.timer.start('Sync content layer');
let store: MutableDataStore | undefined;
try {
const dataStoreFile = getDataStoreFile(settings);
if (existsSync(dataStoreFile)) {
store = await MutableDataStore.fromFile(dataStoreFile);
}
} catch (err: any) {
logger.error('content', err.message);
}
if (!store) {
store = new MutableDataStore();
if (!skip?.content) {
await syncContentCollections(settings, { fs, logger });
settings.timer.start('Sync content layer');
let store: MutableDataStore | undefined;
try {
const dataStoreFile = getDataStoreFile(settings);
if (existsSync(dataStoreFile)) {
store = await MutableDataStore.fromFile(dataStoreFile);
}
const contentLayer = globalContentLayer.init({
settings,
logger,
store,
});
await contentLayer.sync();
settings.timer.end('Sync content layer');
} else if (fs.existsSync(fileURLToPath(getContentPaths(settings.config, fs).contentDir))) {
// Content is synced after writeFiles. That means references are not created
// To work around it, we create a stub so the reference is created and content
// sync will override the empty file
settings.injectedTypes.push({
filename: CONTENT_TYPES_FILE,
content: '',
});
} catch (err: any) {
logger.error('content', err.message);
}
syncAstroEnv(settings, fs);

await writeFiles(settings, fs, logger);
logger.info('types', `Generated ${dim(getTimeStat(timerStart, performance.now()))}`);
} catch (err) {
const error = createSafeError(err);
logger.error(
'types',
formatErrorMessage(collectErrorMetadata(error), logger.level() === 'debug') + '\n',
);
// Will return exit code 1 in CLI
throw error;
if (!store) {
store = new MutableDataStore();
}
const contentLayer = globalContentLayer.init({
settings,
logger,
store,
});
await contentLayer.sync();
settings.timer.end('Sync content layer');
} else if (fs.existsSync(fileURLToPath(getContentPaths(settings.config, fs).contentDir))) {
// Content is synced after writeFiles. That means references are not created
// To work around it, we create a stub so the reference is created and content
// sync will override the empty file
settings.injectedTypes.push({
filename: CONTENT_TYPES_FILE,
content: '',
});
}
syncAstroEnv(settings, fs);

await writeFiles(settings, fs, logger);
logger.info('types', `Generated ${dim(getTimeStat(timerStart, performance.now()))}`);
}

/**
Expand Down Expand Up @@ -223,7 +204,7 @@ async function syncContentCollections(
}
}
} catch (e) {
const safeError = createSafeError(e);
const safeError = createSafeError(e) as ErrorWithMetadata;
if (isAstroError(e)) {
throw e;
}
Expand All @@ -233,6 +214,7 @@ async function syncContentCollections(
...AstroErrorData.GenerateContentTypesError,
hint,
message: AstroErrorData.GenerateContentTypesError.message(safeError.message),
location: safeError.loc,
},
{ cause: e },
);
Expand Down
Loading