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

Check for --config file extensions after they fail to load, allowing custom loaders #3135

Merged
merged 3 commits into from Nov 13, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/cli.js
Expand Up @@ -250,8 +250,8 @@ export default async function loadCli() { // eslint-disable-line complexity
setChalk(chalkOptions);

if (confError) {
if (confError.parent) {
exit(`${confError.message}\n\n${chalk.gray((confError.parent && confError.parent.stack) || confError.parent)}`);
if (confError.cause) {
exit(`${confError.message}\n\n${chalk.gray(confError.cause?.stack ?? confError.cause)}`);
} else {
exit(confError.message);
}
Expand Down
20 changes: 13 additions & 7 deletions lib/load-config.js
Expand Up @@ -29,17 +29,13 @@ const loadConfigFile = async ({projectDir, configFile}) => {
return null;
}

throw Object.assign(new Error(`Error loading ${fileForErrorMessage}: ${error.message}`), {parent: error});
throw Object.assign(new Error(`Error loading ${fileForErrorMessage}: ${error.message}`), {cause: error});
}
};

function resolveConfigFile(configFile) {
if (configFile) {
configFile = path.resolve(configFile); // Relative to CWD

if (!configFile.endsWith('.js') && !configFile.endsWith('.cjs') && !configFile.endsWith('.mjs')) {
throw new Error('Config files must have .js, .cjs or .mjs extensions');
}
}

return configFile;
Expand Down Expand Up @@ -78,7 +74,7 @@ async function checkJsonFile(searchDir) {
}
}

export async function loadConfig({configFile, resolveFrom = process.cwd(), defaults = {}} = {}) {
export async function loadConfig({configFile, resolveFrom = process.cwd(), defaults = {}} = {}) { // eslint-disable-line complexity
let packageConf = await packageConfig('ava', {cwd: resolveFrom});
const filepath = packageJsonPath(packageConf);
const projectDir = filepath === undefined ? resolveFrom : path.dirname(filepath);
Expand All @@ -94,7 +90,17 @@ export async function loadConfig({configFile, resolveFrom = process.cwd(), defau
let fileForErrorMessage;
let conflicting = [];
if (configFile) {
const loaded = await loadConfigFile({projectDir, configFile});
let loaded;
try {
loaded = await loadConfigFile({projectDir, configFile});
} catch (error) {
if (!configFile.endsWith('.js') && !configFile.endsWith('.cjs') && !configFile.endsWith('.mjs')) {
throw Object.assign(new Error('Could not load config file; it should have .js, .cjs or .mjs extension'), {cause: error});
}

throw error;
}

if (loaded !== null) {
({config: fileConf, fileForErrorMessage} = loaded);
}
Expand Down
2 changes: 1 addition & 1 deletion test/config/loader.js
Expand Up @@ -110,7 +110,7 @@ test.serial('receives a `projectDir` property', (...args) => ok('package-only')(
});

test.serial('rethrows wrapped module errors', notOk('throws'), (t, error) => {
t.is(error.parent.message, 'foo');
t.is(error.cause.message, 'foo');
});

test.serial('throws an error if a .js config file has no default export', notOk('no-default-export'));
Expand Down
2 changes: 1 addition & 1 deletion test/config/snapshots/loader.js.md
Expand Up @@ -14,7 +14,7 @@ Generated by [AVA](https://avajs.dev).

> error message

'Config files must have .js, .cjs or .mjs extensions'
'Could not load config file; it should have .js, .cjs or .mjs extension'

## throws an error if a config factory does not return a plain object

Expand Down
Binary file modified test/config/snapshots/loader.js.snap
Binary file not shown.