Skip to content

Commit

Permalink
Use KyRequest and KyResponse types in errors (#610)
Browse files Browse the repository at this point in the history
* feat: additional json convenience methods

- introduces `KyRequest` which, like `KyResponse`, adds `json()` convenience method for extracting JSON with an expected TypeScript type
- update API `Request`/`Response` usages to expose `KyRequest`/`KyResponse` to `ky` consumers so that they may use the `json()` convenience method in more scenarios (`HTTPError`, `TimeoutError`, and hooks)

Refs: #584

* fix unnecessary assertion

* docs(readme): mention `.json()` TS improvements
  • Loading branch information
mfulton26 committed Jul 19, 2024
1 parent 4886b66 commit 8e171f5
Show file tree
Hide file tree
Showing 7 changed files with 19 additions and 9 deletions.
1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ It's just a tiny file with no dependencies.
- URL prefix option
- Instances with custom defaults
- Hooks
- TypeScript niceties (e.g. `.json()` resolves to `unknown`, not `any`; `.json<T>()` can be used too)

## Install

Expand Down
6 changes: 4 additions & 2 deletions source/errors/HTTPError.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
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: Response;
public request: Request;
public response: KyResponse;
public request: KyRequest;
public options: NormalizedOptions;

constructor(response: Response, request: Request, options: NormalizedOptions) {
Expand Down
4 changes: 3 additions & 1 deletion source/errors/TimeoutError.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type {KyRequest} from '../types/request.js';

export class TimeoutError extends Error {
public request: Request;
public request: KyRequest;

constructor(request: Request) {
super(`Request timed out: ${request.method} ${request.url}`);
Expand Down
1 change: 1 addition & 0 deletions source/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export type {
} from './types/hooks.js';

export type {ResponsePromise} from './types/ResponsePromise.js';
export type {KyRequest} from './types/request.js';
export type {KyResponse} from './types/response.js';
export {HTTPError} from './errors/HTTPError.js';
export {TimeoutError} from './errors/TimeoutError.js';
10 changes: 5 additions & 5 deletions source/types/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import {type stop} from '../core/constants.js';
import {type HTTPError} from '../index.js';
import type {KyRequest, KyResponse, HTTPError} from '../index.js';
import type {NormalizedOptions} from './options.js';

export type BeforeRequestHook = (
request: Request,
request: KyRequest,
options: NormalizedOptions
) => Request | Response | void | Promise<Request | Response | void>;

export type BeforeRetryState = {
request: Request;
request: KyRequest;
options: NormalizedOptions;
error: Error;
retryCount: number;
};
export type BeforeRetryHook = (options: BeforeRetryState) => typeof stop | void | Promise<typeof stop | void>;

export type AfterResponseHook = (
request: Request,
request: KyRequest,
options: NormalizedOptions,
response: Response
response: KyResponse
) => Response | void | Promise<Response | void>;

export type BeforeErrorHook = (error: HTTPError) => HTTPError | Promise<HTTPError>;
Expand Down
4 changes: 4 additions & 0 deletions source/types/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,7 @@ type UndiciRequestInit = {
type CombinedRequestInit = globalThis.RequestInit & UndiciRequestInit;

export type RequestInitRegistry = {[K in keyof CombinedRequestInit]-?: true};

export type KyRequest = {
json: <T = unknown>() => Promise<T>;
} & Request;
2 changes: 1 addition & 1 deletion test/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,7 @@ test('beforeError can return promise which resolves to HTTPError', async t => {
beforeError: [
async (error: HTTPError) => {
const {response} = error;
const body = await response.json() as {reason: string};
const body = await response.json<{reason: string}>();

if (response?.body) {
error.name = 'GitHubError';
Expand Down

0 comments on commit 8e171f5

Please sign in to comment.