Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTPError json as unknown/type #584

Closed
mfulton26 opened this issue May 1, 2024 · 3 comments · Fixed by #610
Closed

HTTPError json as unknown/type #584

mfulton26 opened this issue May 1, 2024 · 3 comments · Fixed by #610

Comments

@mfulton26
Copy link
Contributor

mfulton26 commented May 1, 2024

I like how for requests I can chain .json<Foo>() or .json() (for unknown instead of any).

Can this same functionality be added when grabbing an HTTP response body from an HTTPError instance?

@sholladay
Copy link
Collaborator

I think so, but to be sure, can you provide a full usage example?

@mfulton26
Copy link
Contributor Author

Condensed example

Instead of

try {
  // some ky call
} catch (e) {
  const { msg } = (await e.response.json()) as { msg: string };
  // do something with the parsed error response payload
}

I want to be able to write

try {
  // some ky call
} catch (e) {
  const { msg } = await e.response.json<{ msg: string }>();
  // do something with the parsed error response payload
}

so that the I don't need to wrap await e.response.json() inside parameters and explicitly cast

@@ -1,6 +1,6 @@
 try {
   // some ky call
 } catch (e) {
-  const { msg } = (await e.response.json()) as { msg: string };
+  const { msg } = await e.response.json<{ msg: string }>();
   // do something with the parsed error response payload
 }
Longer example

Instead of

import ky, { BeforeRequestHook, HTTPError } from "npm:ky";

function notFound(): BeforeRequestHook {
  return (request, options) => {
    const response = Response.json({ msg: "Not Found" }, {
      status: 404,
    });
    throw new HTTPError(response, request, options);
  };
}

async function updatePostBody(id: string, body: string) {
  try {
    const url = `https://www.example.com/posts/${encodeURIComponent(id)}`;
    const hooks = { beforeRequest: [notFound()] };
    return await ky.put(url, { json: { id, body }, hooks })
      .json<{ id: number; title: string; body: string; userId: number }>();
  } catch (e) {
    if (!(e instanceof HTTPError)) throw e;
    const { msg } = (await e.response.json()) as { msg: string };
    throw Error(`Update failed: ${msg}`);
  }
}

await updatePostBody(crypto.randomUUID(), "42");

I want to be able to change (await e.response.json()) as { msg: string } to await e.response.json<{ msg: string }>() so that I don't need to wrap await e.response.json() inside parentheses and then cast.

@sholladay
Copy link
Collaborator

Yeah, makes sense.

I believe all that is needed is to update HTTPError here:

public response: Response;

… to use the KyResponse type instead of Response:

export type KyResponse = {

mfulton26 added a commit to mfulton26/ky that referenced this issue Jul 16, 2024
- 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: sindresorhus#584
sholladay pushed a commit that referenced this issue Jul 19, 2024
* 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants