Skip to content

Allow for logging network errors and JSON parse errors #605

@danbahrami

Description

@danbahrami

Hi! I'd like to contribute to ky for selfish reasons. I want to use it in my org's production app however, after trying to hook up the necessary logging we need I've come to a dead end.

The logging that I need is:

  • at the start of every request (the beforeRequest hook works for this)
  • at the end of every request (afterResponse works for success and HTTPError responses but not Network Errors)
  • when a network error is received (there are no hooks that currently cover this case)
  • when Response.json() fails

So that leaves me with two gaps:

  1. Hooking into Response.json() errors
  2. Hooking into network errors

I'd like to get a rough steer on an approach for these both before creating a PR.

Hooking into Response.json() errors

My first attempt at this was to try to do it in my own parseJson method:

const api = ky.create({
    ...
    parseJson: (text) => {
        try {
            JSON.parse(text);
        } catch (e) {
            log(e); // log errors here
            throw e
        }
    }
})

The problem with this approach is that, within the context of parseJson you don't have access to the request context so you can't send any information about the specific request along with the error.

Possible solutions

I can think of two sensible options:

1. Pass the request information to the parseJson option
This would look something like:

const api = ky.create({
    ...
    parseJson: (text, { request, options }) => {
        try {
            JSON.parse(text);
        } catch (e) {
            log(e, { url: request.url, headers: options.headers }); // log errors here
            throw e
        }
    }
})

not sure exactly what you'd want to pass in that second argument, could potentially contain the response as well if that's feasible.

2. A new hook - beforeJsonParseError
This would be more fitting with how we can hook into HTTP Errors.

type BeforeJsonParseErrorState = {
    request: Request;
    options: NormalizedOptions;
    response: Response
    error: Error;
};

type BeforeJsonParseErrorHook = (options: BeforeJsonParseErrorState) => Error | void;

Let me know if either of those sound reasonable or if you have any other ideas.

Hooking into network errors

This is already covered by another issue: #296

With this one I'm not sure if it's worth creating a new hook or expanding the beforeError hook to also run on network errors. Modifying beforeError behaviour would probably require a major version bump as it could be a breaking change but it does feel like the more sensible API.

otherwise I could add a new beforeNetworkError hook

type BeforeNetworkErrorState = {
    request: Request;
    options: NormalizedOptions;
    response: Response
    error: unknown; // probably want to force users to perform their own type narrowing
};

type BeforeNetworkErrorHook = (options: BeforeNetworkErrorState) => Error | Promise<Error> | void ;

Again, please let me know if either of those sound reasonable or if you have any other ideas.

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions