Skip to content

Commit 92ebb2f

Browse files
authored
fix(browser): catch malformed URL TypeError and map to exit 5 VALIDATION_ERROR (#274)
1 parent d78d0d4 commit 92ebb2f

2 files changed

Lines changed: 15 additions & 3 deletions

File tree

src/lib/browser.test.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,16 @@ describe('openInBrowser', () => {
5454
expect(exec).not.toHaveBeenCalled();
5555
});
5656

57-
it('throws on a malformed URL', () => {
57+
it('refuses a malformed URL with exit 5 before spawning', () => {
5858
const exec = vi.fn();
59-
expect(() => openInBrowser('not a url', { exec })).toThrow();
59+
let error: unknown;
60+
try {
61+
openInBrowser('not a url', { exec });
62+
} catch (err) {
63+
error = err;
64+
}
65+
expect(error).toBeInstanceOf(ApiError);
66+
expect((error as ApiError).exitCode).toBe(5);
6067
expect(exec).not.toHaveBeenCalled();
6168
});
6269

src/lib/browser.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,12 @@ export interface OpenInBrowserDeps {
2323
}
2424

2525
export function openInBrowser(url: string, deps: OpenInBrowserDeps = {}): void {
26-
const parsed = new URL(url);
26+
let parsed: URL;
27+
try {
28+
parsed = new URL(url);
29+
} catch {
30+
throw localValidationError('url', 'must be a valid http(s) URL', undefined, 'field');
31+
}
2732
if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {
2833
// User-input error, not an internal failure: classify as VALIDATION_ERROR
2934
// so it maps to exit 5 (like every other bad-argument path), not exit 1.

0 commit comments

Comments
 (0)