Skip to content

Commit

Permalink
Add generic type parameter to HTTPError
Browse files Browse the repository at this point in the history
  • Loading branch information
sholladay committed Aug 13, 2024
1 parent 3b20935 commit b0bd8b2
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 6 deletions.
2 changes: 2 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,8 @@ try {
}
```

⌨️ **TypeScript:** Accepts an optional [type parameter](https://www.typescriptlang.org/docs/handbook/2/generics.html), which defaults to [`unknown`](https://www.typescriptlang.org/docs/handbook/2/functions.html#unknown), and is passed through to the return type of `error.response.json()`.

### TimeoutError

The error thrown when the request times out. It has a `request` property with the [`Request` object](https://developer.mozilla.org/en-US/docs/Web/API/Request).
Expand Down
5 changes: 2 additions & 3 deletions source/errors/HTTPError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import type {NormalizedOptions} from '../types/options.js';
import type {KyRequest} from '../types/request.js';
import type {KyResponse} from '../types/response.js';

// eslint-lint-disable-next-line @typescript-eslint/naming-convention
export class HTTPError extends Error {
public response: KyResponse;
export class HTTPError<T = unknown> extends Error {
public response: KyResponse<T>;
public request: KyRequest;
public options: NormalizedOptions;

Expand Down
22 changes: 19 additions & 3 deletions test/http-error.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import test from 'ava';
import {expectTypeOf} from 'expect-type';
import {HTTPError} from '../source/index.js';
import {type Mutable} from '../source/utils/types.js';

Expand All @@ -14,7 +15,7 @@ function createFakeResponse({status, statusText}: {status?: number; statusText?:

test('HTTPError handles undefined response.statusText', t => {
const status = 500;
// @ts-expect-error missing Request
// @ts-expect-error missing options
const error = new HTTPError(
// This simulates the case where a browser Response object does
// not define statusText, such as IE, Safari, etc.
Expand All @@ -27,7 +28,7 @@ test('HTTPError handles undefined response.statusText', t => {
});

test('HTTPError handles undefined response.status', t => {
// @ts-expect-error missing Request
// @ts-expect-error missing options
const error = new HTTPError(
// This simulates a catastrophic case where some unexpected
// response object was sent to HTTPError.
Expand All @@ -39,7 +40,7 @@ test('HTTPError handles undefined response.status', t => {
});

test('HTTPError handles a response.status of 0', t => {
// @ts-expect-error missing Request
// @ts-expect-error missing options
const error = new HTTPError(
// Apparently, it's possible to get a response status of 0.
createFakeResponse({statusText: undefined, status: 0}),
Expand All @@ -48,3 +49,18 @@ test('HTTPError handles a response.status of 0', t => {

t.is(error.message, 'Request failed with status code 0: GET invalid:foo');
});

test('HTTPError provides response.json()', async t => {
// @ts-expect-error missing options
const error = new HTTPError<{foo: 'bar'}>(
new Response(JSON.stringify({foo: 'bar'})),
new Request('invalid:foo'),
);

const responseJson = await error.response.json();

expectTypeOf(responseJson).toEqualTypeOf<{foo: 'bar'}>();

t.true(error.response instanceof Response);
t.deepEqual(responseJson, {foo: 'bar'});
});

0 comments on commit b0bd8b2

Please sign in to comment.