mirror of
https://github.com/withastro/astro.git
synced 2024-12-30 22:03:56 -05:00
fix: better logs for invalid content config (#12798)
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
This commit is contained in:
parent
5f4c543609
commit
7b0cb852f6
6 changed files with 69 additions and 4 deletions
5
.changeset/afraid-sloths-shake.md
Normal file
5
.changeset/afraid-sloths-shake.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Improves warning logs for invalid content collection configuration
|
|
@ -138,8 +138,15 @@ export class ContentLayer {
|
||||||
async #doSync(options: RefreshContentOptions) {
|
async #doSync(options: RefreshContentOptions) {
|
||||||
const contentConfig = globalContentConfigObserver.get();
|
const contentConfig = globalContentConfigObserver.get();
|
||||||
const logger = this.#logger.forkIntegrationLogger('content');
|
const logger = this.#logger.forkIntegrationLogger('content');
|
||||||
|
|
||||||
|
if (contentConfig?.status === 'error') {
|
||||||
|
logger.error(`Error loading content config. Skipping sync.\n${contentConfig.error.message}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// It shows as loaded with no collections even if there's no config
|
||||||
if (contentConfig?.status !== 'loaded') {
|
if (contentConfig?.status !== 'loaded') {
|
||||||
logger.debug('Content config not loaded, skipping sync');
|
logger.error('Content config not loaded, skipping sync');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { promises as fs } from 'node:fs';
|
import { promises as fs, existsSync } from 'node:fs';
|
||||||
|
import { relative } from 'node:path';
|
||||||
import { fileURLToPath, pathToFileURL } from 'node:url';
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
||||||
import fastGlob from 'fast-glob';
|
import fastGlob from 'fast-glob';
|
||||||
import { bold, green } from 'kleur/colors';
|
import { bold, green } from 'kleur/colors';
|
||||||
|
@ -215,10 +216,27 @@ export function glob(globOptions: GlobOptions): Loader {
|
||||||
baseDir.pathname = `${baseDir.pathname}/`;
|
baseDir.pathname = `${baseDir.pathname}/`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const filePath = fileURLToPath(baseDir);
|
||||||
|
const relativePath = relative(fileURLToPath(config.root), filePath);
|
||||||
|
|
||||||
|
const exists = existsSync(baseDir);
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
// We warn and don't return because we will still set up the watcher in case the directory is created later
|
||||||
|
logger.warn(`The base directory "${fileURLToPath(baseDir)}" does not exist.`);
|
||||||
|
}
|
||||||
|
|
||||||
const files = await fastGlob(globOptions.pattern, {
|
const files = await fastGlob(globOptions.pattern, {
|
||||||
cwd: fileURLToPath(baseDir),
|
cwd: fileURLToPath(baseDir),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (exists && files.length === 0) {
|
||||||
|
logger.warn(
|
||||||
|
`No files found matching "${globOptions.pattern}" in directory "${relativePath}"`,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
function configForFile(file: string) {
|
function configForFile(file: string) {
|
||||||
const ext = file.split('.').at(-1);
|
const ext = file.split('.').at(-1);
|
||||||
if (!ext) {
|
if (!ext) {
|
||||||
|
|
|
@ -111,7 +111,7 @@ export function createGetCollection({
|
||||||
console.warn(
|
console.warn(
|
||||||
`The collection ${JSON.stringify(
|
`The collection ${JSON.stringify(
|
||||||
collection,
|
collection,
|
||||||
)} does not exist or is empty. Ensure a collection directory with this name exists.`,
|
)} does not exist or is empty. Please check your content config file for errors.`,
|
||||||
);
|
);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,11 @@ import assert from 'node:assert/strict';
|
||||||
import { promises as fs, existsSync } from 'node:fs';
|
import { promises as fs, existsSync } from 'node:fs';
|
||||||
import { sep } from 'node:path';
|
import { sep } from 'node:path';
|
||||||
import { sep as posixSep } from 'node:path/posix';
|
import { sep as posixSep } from 'node:path/posix';
|
||||||
|
import { Writable } from 'node:stream';
|
||||||
import { after, before, describe, it } from 'node:test';
|
import { after, before, describe, it } from 'node:test';
|
||||||
import * as cheerio from 'cheerio';
|
import * as cheerio from 'cheerio';
|
||||||
import * as devalue from 'devalue';
|
import * as devalue from 'devalue';
|
||||||
|
import { Logger } from '../dist/core/logger/core.js';
|
||||||
|
|
||||||
import { loadFixture } from './test-utils.js';
|
import { loadFixture } from './test-utils.js';
|
||||||
describe('Content Layer', () => {
|
describe('Content Layer', () => {
|
||||||
|
@ -316,8 +318,21 @@ describe('Content Layer', () => {
|
||||||
describe('Dev', () => {
|
describe('Dev', () => {
|
||||||
let devServer;
|
let devServer;
|
||||||
let json;
|
let json;
|
||||||
|
const logs = [];
|
||||||
before(async () => {
|
before(async () => {
|
||||||
devServer = await fixture.startDevServer({ force: true });
|
devServer = await fixture.startDevServer({
|
||||||
|
force: true,
|
||||||
|
logger: new Logger({
|
||||||
|
level: 'warn',
|
||||||
|
dest: new Writable({
|
||||||
|
objectMode: true,
|
||||||
|
write(event, _, callback) {
|
||||||
|
logs.push(event);
|
||||||
|
callback();
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
});
|
||||||
// Vite may not have noticed the saved data store yet. Wait a little just in case.
|
// Vite may not have noticed the saved data store yet. Wait a little just in case.
|
||||||
await fixture.onNextDataStoreChange(1000).catch(() => {
|
await fixture.onNextDataStoreChange(1000).catch(() => {
|
||||||
// Ignore timeout, because it may have saved before we get here.
|
// Ignore timeout, because it may have saved before we get here.
|
||||||
|
@ -331,6 +346,16 @@ describe('Content Layer', () => {
|
||||||
devServer?.stop();
|
devServer?.stop();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("warns about missing directory in glob() loader's path", async () => {
|
||||||
|
assert.ok(logs.find((log) => log.level === 'warn' && log.message.includes('does not exist')));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("warns about missing files in glob() loader's path", async () => {
|
||||||
|
assert.ok(
|
||||||
|
logs.find((log) => log.level === 'warn' && log.message.includes('No files found matching')),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('Generates content types files', async () => {
|
it('Generates content types files', async () => {
|
||||||
assert.ok(existsSync(new URL('./.astro/content.d.ts', fixture.config.root)));
|
assert.ok(existsSync(new URL('./.astro/content.d.ts', fixture.config.root)));
|
||||||
const data = await fs.readFile(new URL('./.astro/types.d.ts', fixture.config.root), 'utf-8');
|
const data = await fs.readFile(new URL('./.astro/types.d.ts', fixture.config.root), 'utf-8');
|
||||||
|
|
|
@ -177,6 +177,13 @@ const numbers = defineCollection({
|
||||||
loader: glob({ pattern: 'src/data/glob-data/*', base: '.' }),
|
loader: glob({ pattern: 'src/data/glob-data/*', base: '.' }),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const notADirectory = defineCollection({
|
||||||
|
loader: glob({ pattern: '*', base: 'src/nonexistent' }),
|
||||||
|
});
|
||||||
|
|
||||||
|
const nothingMatches = defineCollection({
|
||||||
|
loader: glob({ pattern: 'nothingmatches/*', base: 'src/data' }),
|
||||||
|
});
|
||||||
const images = defineCollection({
|
const images = defineCollection({
|
||||||
loader: () => [
|
loader: () => [
|
||||||
{
|
{
|
||||||
|
@ -259,4 +266,7 @@ export const collections = {
|
||||||
songs,
|
songs,
|
||||||
probes,
|
probes,
|
||||||
rodents,
|
rodents,
|
||||||
|
notADirectory,
|
||||||
|
nothingMatches
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue