Skip to content

Commit 2b200f1

Browse files
authored
fix(error): wrap and re-throw errors (#252)
* fix(error): wrap and re-throw errors * handle errors sync and async * move to utils, add lazy
1 parent 0c04871 commit 2b200f1

File tree

3 files changed

+45
-9
lines changed

3 files changed

+45
-9
lines changed

bin/cli.mjs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { Argument, Command, Option } from 'commander';
66
import interactive from './commands/interactive.mjs';
77
import list, { types } from './commands/list.mjs';
88
import commands from './commands/index.mjs';
9+
import { errorWrap } from './utils.mjs';
910

1011
const program = new Command()
1112
.name('api-docs-tooling')
@@ -33,21 +34,21 @@ commands.forEach(({ name, description, options, action }) => {
3334
});
3435

3536
// Set the action for the command
36-
cmd.action(action);
37+
cmd.action(errorWrap(action));
3738
});
3839

3940
// Register the interactive command
4041
program
4142
.command('interactive')
4243
.description('Launch guided CLI wizard')
43-
.action(interactive);
44+
.action(errorWrap(interactive));
4445

4546
// Register the list command
4647
program
4748
.command('list')
4849
.addArgument(new Argument('<types>', 'The type to list').choices(types))
4950
.description('List the given type')
50-
.action(list);
51+
.action(errorWrap(list));
5152

5253
// Parse and execute command-line arguments
5354
program.parse(process.argv);

bin/utils.mjs

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
11
import createMarkdownLoader from '../src/loaders/markdown.mjs';
22
import createMarkdownParser from '../src/parsers/markdown.mjs';
33

4-
// Instantiate loader and parser once to reuse
5-
const loader = createMarkdownLoader();
6-
const parser = createMarkdownParser();
4+
/**
5+
* Generic lazy initializer.
6+
* @template T
7+
* @param {() => T} factory - Function to create the instance.
8+
* @returns {() => T} - A function that returns the singleton instance.
9+
*/
10+
export const lazy = factory => {
11+
let instance;
12+
return () => (instance ??= factory());
13+
};
14+
15+
// Instantiate loader and parser once to reuse,
16+
// but only if/when we actually need them. No need
17+
// to create these objects just to load a different
18+
// utility.
19+
const loader = lazy(createMarkdownLoader);
20+
const parser = lazy(createMarkdownParser);
721

822
/**
923
* Load and parse markdown API docs.
@@ -12,10 +26,27 @@ const parser = createMarkdownParser();
1226
* @returns {Promise<ApiDocMetadataEntry[]>} - Parsed documentation objects.
1327
*/
1428
export async function loadAndParse(input, ignore) {
15-
const files = await loader.loadFiles(input, ignore);
16-
return parser.parseApiDocs(files);
29+
const files = await loader().loadFiles(input, ignore);
30+
return parser().parseApiDocs(files);
1731
}
1832

33+
/**
34+
* Wraps a function to catch both synchronous and asynchronous errors.
35+
*
36+
* @param {Function} fn - The function to wrap. Can be synchronous or return a Promise.
37+
* @returns {Function} A new function that handles errors and logs them.
38+
*/
39+
export const errorWrap =
40+
fn =>
41+
async (...args) => {
42+
try {
43+
return await fn(...args);
44+
} catch (err) {
45+
console.error(err);
46+
process.exit(1);
47+
}
48+
};
49+
1950
/**
2051
* Represents a command-line option for the linter CLI.
2152
* @typedef {Object} Option

src/threading/index.mjs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,11 @@ export default class WorkerPool {
5656
this.changeActiveThreadCount(-1);
5757
this.processQueue(threads);
5858

59-
(result?.error ? reject : resolve)(result);
59+
if (result?.error) {
60+
reject(result.error);
61+
} else {
62+
resolve(result);
63+
}
6064
});
6165

6266
// Handle worker thread errors

0 commit comments

Comments
 (0)