Skip to content

Commit c4726d7

Browse files
apatel369ematipicoPrincesseuh
authoredNov 6, 2024··
fix: show file name with invalid frontmatter errors for MDX (#12355)
Co-authored-by: Emanuele Stoppa <my.burning@gmail.com> Co-authored-by: Princesseuh <3019731+Princesseuh@users.noreply.github.com>
1 parent 4c9a42c commit c4726d7

File tree

6 files changed

+50
-63
lines changed

6 files changed

+50
-63
lines changed
 

‎.changeset/wise-bulldogs-jump.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'astro': patch
3+
---
4+
5+
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.

‎packages/astro/src/cli/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,8 @@ async function runCommand(cmd: string, flags: yargs.Arguments) {
133133
}
134134
case 'sync': {
135135
const { sync } = await import('./sync/index.js');
136-
const exitCode = await sync({ flags });
137-
return process.exit(exitCode);
136+
await sync({ flags });
137+
return;
138138
}
139139
case 'preferences': {
140140
const { preferences } = await import('./preferences/index.js');

‎packages/astro/src/cli/sync/index.ts

+1-6
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,5 @@ export async function sync({ flags }: SyncOptions) {
2222
return 0;
2323
}
2424

25-
try {
26-
await _sync(flagsToAstroInlineConfig(flags), { telemetry: true });
27-
return 0;
28-
} catch (_) {
29-
return 1;
30-
}
25+
await _sync(flagsToAstroInlineConfig(flags), { telemetry: true });
3126
}

‎packages/astro/src/core/errors/errors-data.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1388,7 +1388,7 @@ export const GenerateContentTypesError = {
13881388
title: 'Failed to generate content types.',
13891389
message: (errorMessage: string) =>
13901390
`\`astro sync\` command failed to generate content collection types: ${errorMessage}`,
1391-
hint: 'Check your `src/content/config.*` file for typos.',
1391+
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.',
13921392
} satisfies ErrorData;
13931393
/**
13941394
* @docs

‎packages/astro/src/core/messages.ts

+5
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,11 @@ export function formatErrorMessage(err: ErrorWithMetadata, showFullStacktrace: b
298298
output.push(` ${cyan(underline(docsLink))}`);
299299
}
300300

301+
if (showFullStacktrace && err.loc) {
302+
output.push(` ${bold('Location:')}`);
303+
output.push(` ${underline(`${err.loc.file}:${err.loc.line ?? 0}:${err.loc.column ?? 0}`)}`);
304+
}
305+
301306
if (err.stack) {
302307
output.push(` ${bold('Stack trace:')}`);
303308
output.push(dim(formatErrorStackTrace(err, showFullStacktrace)));

‎packages/astro/src/core/sync/index.ts

+36-54
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
AstroError,
2424
AstroErrorData,
2525
AstroUserError,
26+
type ErrorWithMetadata,
2627
createSafeError,
2728
isAstroError,
2829
} from '../errors/index.js';
@@ -62,17 +63,7 @@ export default async function sync(
6263
logger,
6364
});
6465

65-
// Run `astro:config:done`
66-
// Actions will throw if there is misconfiguration, so catch here.
67-
try {
68-
await runHookConfigDone({ settings, logger });
69-
} catch (err) {
70-
if (err instanceof Error) {
71-
const errorMessage = err.toString();
72-
logger.error('sync', errorMessage);
73-
}
74-
throw err;
75-
}
66+
await runHookConfigDone({ settings, logger });
7667

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

113104
const timerStart = performance.now();
114105

115-
try {
116-
if (!skip?.content) {
117-
await syncContentCollections(settings, { fs, logger });
118-
settings.timer.start('Sync content layer');
119-
let store: MutableDataStore | undefined;
120-
try {
121-
const dataStoreFile = getDataStoreFile(settings);
122-
if (existsSync(dataStoreFile)) {
123-
store = await MutableDataStore.fromFile(dataStoreFile);
124-
}
125-
} catch (err: any) {
126-
logger.error('content', err.message);
127-
}
128-
if (!store) {
129-
store = new MutableDataStore();
106+
if (!skip?.content) {
107+
await syncContentCollections(settings, { fs, logger });
108+
settings.timer.start('Sync content layer');
109+
let store: MutableDataStore | undefined;
110+
try {
111+
const dataStoreFile = getDataStoreFile(settings);
112+
if (existsSync(dataStoreFile)) {
113+
store = await MutableDataStore.fromFile(dataStoreFile);
130114
}
131-
const contentLayer = globalContentLayer.init({
132-
settings,
133-
logger,
134-
store,
135-
});
136-
await contentLayer.sync();
137-
settings.timer.end('Sync content layer');
138-
} else if (fs.existsSync(fileURLToPath(getContentPaths(settings.config, fs).contentDir))) {
139-
// Content is synced after writeFiles. That means references are not created
140-
// To work around it, we create a stub so the reference is created and content
141-
// sync will override the empty file
142-
settings.injectedTypes.push({
143-
filename: CONTENT_TYPES_FILE,
144-
content: '',
145-
});
115+
} catch (err: any) {
116+
logger.error('content', err.message);
146117
}
147-
syncAstroEnv(settings, fs);
148-
149-
await writeFiles(settings, fs, logger);
150-
logger.info('types', `Generated ${dim(getTimeStat(timerStart, performance.now()))}`);
151-
} catch (err) {
152-
const error = createSafeError(err);
153-
logger.error(
154-
'types',
155-
formatErrorMessage(collectErrorMetadata(error), logger.level() === 'debug') + '\n',
156-
);
157-
// Will return exit code 1 in CLI
158-
throw error;
118+
if (!store) {
119+
store = new MutableDataStore();
120+
}
121+
const contentLayer = globalContentLayer.init({
122+
settings,
123+
logger,
124+
store,
125+
});
126+
await contentLayer.sync();
127+
settings.timer.end('Sync content layer');
128+
} else if (fs.existsSync(fileURLToPath(getContentPaths(settings.config, fs).contentDir))) {
129+
// Content is synced after writeFiles. That means references are not created
130+
// To work around it, we create a stub so the reference is created and content
131+
// sync will override the empty file
132+
settings.injectedTypes.push({
133+
filename: CONTENT_TYPES_FILE,
134+
content: '',
135+
});
159136
}
137+
syncAstroEnv(settings, fs);
138+
139+
await writeFiles(settings, fs, logger);
140+
logger.info('types', `Generated ${dim(getTimeStat(timerStart, performance.now()))}`);
160141
}
161142

162143
/**
@@ -223,7 +204,7 @@ async function syncContentCollections(
223204
}
224205
}
225206
} catch (e) {
226-
const safeError = createSafeError(e);
207+
const safeError = createSafeError(e) as ErrorWithMetadata;
227208
if (isAstroError(e)) {
228209
throw e;
229210
}
@@ -233,6 +214,7 @@ async function syncContentCollections(
233214
...AstroErrorData.GenerateContentTypesError,
234215
hint,
235216
message: AstroErrorData.GenerateContentTypesError.message(safeError.message),
217+
location: safeError.loc,
236218
},
237219
{ cause: e },
238220
);

0 commit comments

Comments
 (0)
Please sign in to comment.