Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions src/baza.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@ export const baza = async function(path: string, method: string,
let response: Response;
try {
response = await fetch(uri, meta);
} catch (e) {
throw new Error(
`Network failure for ${method} ${uri}: ${(e as Error).message}`
} catch (error: unknown) {
const reason = error instanceof Error ? error.message : String(error);
const failure = new Error(
`Network failure for ${method} ${uri}: ${reason}`
);
Object.defineProperty(failure, 'cause', { value: error });
throw failure;
}
if (response.status != 200) {
let error = `HTTP error ${response.status}`;
Expand Down
40 changes: 28 additions & 12 deletions test/baza.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,38 @@ describe('baza', () => {
).rejects.toThrow('HTTP error 404');
});

test('does not follow redirects', async () => {
await expect(
baza('/redirect', 'PUT', {}, '')
).rejects.toThrow('HTTP error 303');
test('wraps network failures', async (): Promise<void> => {
const failure = new TypeError('fetch failed');
const fetch = jest.spyOn(globalThis, 'fetch').mockRejectedValue(failure);
let thrown: unknown;
try {
await baza('/robots.txt', 'GET', {}, '');
} catch (error: unknown) {
thrown = error;
} finally {
fetch.mockRestore();
}
expect(thrown).toBeInstanceOf(Error);
expect((thrown as Error).message).toBe(
`Network failure for GET ${host}/robots.txt?: fetch failed`
);
expect(Object.getOwnPropertyDescriptor(thrown, 'cause')?.value).toBe(failure);
});

test('wraps network failures in typed Error', async () => {
const mock = jest.spyOn(globalThis, 'fetch');
mock.mockRejectedValue(new TypeError('fetch failed'));
test('wraps non-error network failures', async (): Promise<void> => {
const fetch = jest.spyOn(globalThis, 'fetch').mockRejectedValue('socket closed');
try {
await expect(baza('/test', 'GET', {}, '')).rejects.toThrow(Error);
await expect(baza('/test', 'GET', {}, '')).rejects.toThrow(
'Network failure for GET'
);
await expect(
baza('/robots.txt', 'GET', {}, '')
).rejects.toThrow(`Network failure for GET ${host}/robots.txt?: socket closed`);
} finally {
mock.mockRestore();
fetch.mockRestore();
}
});

test('does not follow redirects', async () => {
await expect(
baza('/redirect', 'PUT', {}, '')
).rejects.toThrow('HTTP error 303');
});
});
Loading