Skip to content

Commit 3ec550b

Browse files
committed
test(linter/plugins): include stack trace in plugin loading errors
1 parent f921bbb commit 3ec550b

File tree

5 files changed

+56
-7
lines changed

5 files changed

+56
-7
lines changed

apps/oxlint/src-js/plugins/utils.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
*/
1515
export function getErrorMessage(err: unknown): string {
1616
try {
17+
if (err instanceof Error) {
18+
const { stack } = err;
19+
if (typeof stack === 'string') return stack;
20+
}
21+
1722
const { message } = err as undefined | { message: string };
1823
if (typeof message === 'string' && message !== '') return message;
1924
} catch {}

apps/oxlint/test/__snapshots__/e2e.test.ts.snap

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -444,18 +444,27 @@ exports[`oxlint CLI > should report an error if a a rule is not found within a c
444444
"
445445
`;
446446

447-
exports[`oxlint CLI > should report an error if a custom plugin cannot be loaded 1`] = `
447+
exports[`oxlint CLI > should report an error if a custom plugin in config but JS plugins are not enabled 1`] = `
448+
"Failed to parse configuration file.
449+
450+
x JS plugins are not supported without \`--experimental-js-plugins\` CLI option
451+
"
452+
`;
453+
454+
exports[`oxlint CLI > should report an error if a custom plugin is missing 1`] = `
448455
"Failed to parse configuration file.
449456
450457
x Failed to load JS plugin: ./test_plugin
451458
| Cannot find module './test_plugin'
452459
"
453460
`;
454461

455-
exports[`oxlint CLI > should report an error if a custom plugin in config but JS plugins are not enabled 1`] = `
462+
exports[`oxlint CLI > should report an error if a custom plugin throws an error during import 1`] = `
456463
"Failed to parse configuration file.
457464
458-
x JS plugins are not supported without \`--experimental-js-plugins\` CLI option
465+
x Failed to load JS plugin: ./test_plugin
466+
| Error: whoops!
467+
| at <root>/apps/oxlint/test/fixtures/custom_plugin_import_error/test_plugin/index.js:1:7
459468
"
460469
`;
461470

apps/oxlint/test/e2e.test.ts

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { execa } from 'execa';
66

77
const PACKAGE_ROOT_PATH = dirname(import.meta.dirname);
88
const CLI_PATH = pathJoin(PACKAGE_ROOT_PATH, 'dist/cli.js');
9+
const ROOT_URL = new URL('../../../', import.meta.url).href;
10+
const FIXTURES_URL = new URL('./fixtures/', import.meta.url).href;
911

1012
async function runOxlintWithoutPlugins(cwd: string, args: string[] = []) {
1113
return await execa('node', [CLI_PATH, ...args], {
@@ -19,9 +21,28 @@ async function runOxlint(cwd: string, args: string[] = []) {
1921
}
2022

2123
function normalizeOutput(output: string): string {
22-
return output
23-
.replace(/Finished in \d+(\.\d+)?(s|ms|us|ns)/, 'Finished in Xms')
24-
.replace(/using \d+ threads./, 'using X threads.');
24+
let lines = output.split('\n');
25+
26+
// Remove timing and thread count info which can vary between runs
27+
lines[lines.length - 1] = lines[lines.length - 1].replace(
28+
/^Finished in \d+(?:\.\d+)?(?:s|ms|us|ns) on (\d+) file(s?) using \d+ threads.$/,
29+
'Finished in Xms on $1 file$2 using X threads.',
30+
);
31+
32+
// Remove lines from stack traces which are outside `fixtures` directory.
33+
// Replace path to repo root in stack traces with `<root>`.
34+
lines = lines.flatMap((line) => {
35+
// e.g. ` | at file:///path/to/oxc/apps/oxlint/test/fixtures/foor/bar.js:1:1`
36+
// e.g. ` | at whatever (file:///path/to/oxc/apps/oxlint/test/fixtures/foor/bar.js:1:1)`
37+
const match = line.match(/^(\s*\|\s+at (?:.+?\()?)(.+)$/);
38+
if (match) {
39+
const [, premable, at] = match;
40+
return at.startsWith(FIXTURES_URL) ? [`${premable}<root>/${at.slice(ROOT_URL.length)}`] : [];
41+
}
42+
return [line];
43+
});
44+
45+
return lines.join('\n');
2546
}
2647

2748
describe('oxlint CLI', () => {
@@ -73,12 +94,18 @@ describe('oxlint CLI', () => {
7394
expect(normalizeOutput(stdout)).toMatchSnapshot();
7495
});
7596

76-
it('should report an error if a custom plugin cannot be loaded', async () => {
97+
it('should report an error if a custom plugin is missing', async () => {
7798
const { stdout, exitCode } = await runOxlint('test/fixtures/missing_custom_plugin');
7899
expect(exitCode).toBe(1);
79100
expect(normalizeOutput(stdout)).toMatchSnapshot();
80101
});
81102

103+
it('should report an error if a custom plugin throws an error during import', async () => {
104+
const { stdout, exitCode } = await runOxlint('test/fixtures/custom_plugin_import_error');
105+
expect(exitCode).toBe(1);
106+
expect(normalizeOutput(stdout)).toMatchSnapshot();
107+
});
108+
82109
it('should report an error if a rule is not found within a custom plugin', async () => {
83110
const { stdout, exitCode } = await runOxlint('test/fixtures/custom_plugin_missing_rule');
84111
expect(exitCode).toBe(1);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"plugins": ["./test_plugin"],
3+
"categories": { "correctness": "off" },
4+
"rules": {
5+
"basic-custom-plugin/unknown-rule": "error"
6+
}
7+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
throw new Error("whoops!");

0 commit comments

Comments
 (0)