Skip to content

Commit c785d9c

Browse files
Fix error messages when tsd fails (#189)
1 parent 58b85ce commit c785d9c

File tree

5 files changed

+39
-6
lines changed

5 files changed

+39
-6
lines changed

source/cli.ts

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/usr/bin/env node
22
import meow from 'meow';
3+
import {TsdError} from './lib/interfaces';
34
import formatter from './lib/formatter';
45
import tsd from './lib';
56

@@ -75,6 +76,11 @@ const exit = (message: string, {isError = true}: {isError?: boolean} = {}) => {
7576
}
7677
} catch (error: unknown) {
7778
const potentialError = error as Error | undefined;
79+
80+
if (potentialError instanceof TsdError) {
81+
exit(potentialError.message);
82+
}
83+
7884
const errorMessage = potentialError?.stack ?? potentialError?.message ?? 'tsd unexpectedly crashed.';
7985

8086
exit(`Error running tsd:\n${errorMessage}`);

source/lib/index.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import globby from 'globby';
55
import {getDiagnostics as getTSDiagnostics} from './compiler';
66
import loadConfig from './config';
77
import getCustomDiagnostics from './rules';
8-
import {Context, Config, Diagnostic, PackageJsonWithTsdConfig} from './interfaces';
8+
import {Context, Config, Diagnostic, PackageJsonWithTsdConfig, TsdError} from './interfaces';
99

1010
export interface Options {
1111
cwd: string;
@@ -25,7 +25,7 @@ const findTypingsFile = async (pkg: PackageJsonWithTsdConfig, options: Options):
2525
const typingsExist = await pathExists(typingsPath);
2626

2727
if (!typingsExist) {
28-
throw new Error(`The type definition \`${typings}\` does not exist at \`${typingsPath}\`. Is the path correct? Create one and try again.`);
28+
throw new TsdError(`The type definition \`${typings}\` does not exist at \`${typingsPath}\`. Is the path correct? Create one and try again.`);
2929
}
3030

3131
return typings;
@@ -43,7 +43,7 @@ const findCustomTestFiles = async (testFilesPattern: readonly string[], cwd: str
4343
const testFiles = await globby(testFilesPattern, {cwd});
4444

4545
if (testFiles.length === 0) {
46-
throw new Error('Could not find any test files with the given pattern(s). Create one and try again.');
46+
throw new TsdError('Could not find any test files with the given pattern(s). Create one and try again.');
4747
}
4848

4949
return testFiles.map(file => path.join(cwd, file));
@@ -65,7 +65,7 @@ const findTestFiles = async (typingsFilePath: string, options: Options & {config
6565
const testDirExists = await pathExists(path.join(options.cwd, testDir));
6666

6767
if (testFiles.length === 0 && !testDirExists) {
68-
throw new Error(`The test file \`${testFile}\` or \`${tsxTestFile}\` does not exist in \`${options.cwd}\`. Create one and try again.`);
68+
throw new TsdError(`The test file \`${testFile}\` or \`${tsxTestFile}\` does not exist in \`${options.cwd}\`. Create one and try again.`);
6969
}
7070

7171
if (testFiles.length === 0) {
@@ -84,7 +84,7 @@ export default async (options: Options = {cwd: process.cwd()}): Promise<Diagnost
8484
const pkgResult = await readPkgUp({cwd: options.cwd});
8585

8686
if (!pkgResult) {
87-
throw new Error(`No \`package.json\` file found in \`${options.cwd}\`. Make sure you are running the command in a Node.js project.`);
87+
throw new TsdError(`No \`package.json\` file found in \`${options.cwd}\`. Make sure you are running the command in a Node.js project.`);
8888
}
8989

9090
const pkg = pkgResult.packageJson as PackageJsonWithTsdConfig;

source/lib/interfaces.ts

+7
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,10 @@ export interface Location {
7171
start: number;
7272
end: number;
7373
}
74+
75+
export class TsdError extends Error {
76+
constructor(message: string) {
77+
super(message);
78+
this.name = this.constructor.name;
79+
}
80+
}

source/test/cli.ts

+9
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,12 @@ test('warnings are reported with errors', async t => {
191191
'1 error',
192192
]);
193193
});
194+
195+
test('tsd failures (not crashes) report only the message', async t => {
196+
const cwd = path.join(__dirname, 'fixtures/no-tsd');
197+
198+
const {exitCode, stderr} = await t.throwsAsync<ExecaError>(execa('../../../cli.js', {cwd}));
199+
200+
t.is(exitCode, 1);
201+
t.is(stderr, `The type definition \`index.d.ts\` does not exist at \`${cwd}/index.d.ts\`. Is the path correct? Create one and try again.`);
202+
});

source/test/test.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import path from 'path';
22
import test from 'ava';
33
import {verify, verifyWithFileName} from './fixtures/utils';
44
import tsd from '..';
5-
import {Diagnostic} from '../lib/interfaces';
5+
import {Diagnostic, TsdError} from '../lib/interfaces';
66

77
test('throw if no type definition was found', async t => {
88
const cwd = path.join(__dirname, 'fixtures/no-tsd');
@@ -427,3 +427,14 @@ test('parsing undefined symbol should not fail', async t => {
427427

428428
verify(t, diagnostics, []);
429429
});
430+
431+
test('custom tsd errors are created correctly', t => {
432+
const tsdError = t.throws<TsdError>(() => {
433+
throw new TsdError('foo');
434+
});
435+
436+
t.true(tsdError instanceof Error);
437+
t.true(tsdError instanceof TsdError);
438+
t.is(tsdError.name, 'TsdError');
439+
t.is(tsdError.message, 'foo');
440+
});

0 commit comments

Comments
 (0)