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

Improve Error Handling for Better Integration with React Query #642

Open
yslpn opened this issue Oct 6, 2024 · 0 comments
Open

Improve Error Handling for Better Integration with React Query #642

yslpn opened this issue Oct 6, 2024 · 0 comments

Comments

@yslpn
Copy link

yslpn commented Oct 6, 2024

Improve Error Handling for Better Integration with React Query

Current Behavior

Currently, when an error occurs in a Ky request, the error object contains a promise that needs to be resolved to access the error details. This differs from Axios, where error details are immediately available in the error.response.data property.

This difference creates challenges when using Ky with libraries like React Query, especially when trying to render error messages immediately after a failed mutation.

Desired Behavior

It would be beneficial if Ky could provide immediate access to parsed error information, similar to Axios. This would allow for more straightforward error handling and rendering in React applications, particularly when used with React Query.

Example of Current Issue

Consider this example using React Query with Axios:

import { useMutation } from '@tanstack/react-query';
import axios from 'axios';

function MyComponent() {
  const { mutate, isError, error, reset } = useMutation({
    mutationFn: (data) => axios.post('https://api.example.com/data', data),
  });

  return (
    <div>
      <button onClick={() => mutate({ some: 'data' })}>Submit</button>
      {isError && (
        <Alert severity="error" onClose={reset}>
          {error.response?.data.message}
        </Alert>
      )}
    </div>
  );
}

In this Axios example, error.response.data.message is immediately available for rendering.

Now, let's look at the same example using Ky:

import { useMutation } from '@tanstack/react-query';
import ky from 'ky';
import { useState } from 'react';

function MyComponent() {
  const [error, setError] = useState(null);

  const { mutate, isError, reset } = useMutation({
    mutationFn: (data) => ky.post('https://api.example.com/data', { json: data }).json(),
    onError: async (error, variables, context) => {
      if (error.response) {
        // Await the json response from the error
        const jsonError = await error.response.json();
        setError(jsonError); // Save the error to state
      } else {
        setError({message: 'An unexpected error occurred'});
      }
    }
  });

  return (
    <div>
      <button onClick={() => { mutate({ some: 'data' }); reset(); }}>Submit</button>
      {isError && error && (
        <Alert severity="error" onClose={() => { reset(); setError(null); }}>
          {error.message}
        </Alert>
      )}
    </div>
  );
}

In this Ky example, error.response.json() is a promise, so error.response?.data.message is not immediately available. We would need to await the promise before we can access the error details and create new state with errors, which complicates the rendering process.

Additional Complexity

The current Ky implementation adds further complexity because the promise represents not just the response, but also the request. This means that in some scenarios, we might need to call .json() twice: once for sending the request and once for parsing the error.request.json()

Proposed Solution

One possible solution could be to automatically parse the error response and make it immediately available, similar to Axios. For example:

ky.post('https://api.example.com/data', { json: data })
  .json()
  .catch(error => {
    if (error instanceof HTTPError) {
      const responseData = await error.response.json();
      throw {
        ...error,
        response: {
          data: responseData,
          status: error.response.status,
          statusText: error.response.statusText,
        },
      };
    }
    throw error;
  });

This would allow Ky to behave more like Axios in error scenarios, making it easier to use with React Query and similar libraries. But when developing this option, it requires creating a new error class to type react-query correctly and writing additional code.

Questions for Consideration

  1. Is it feasible to change Ky's error handling to more closely match Axios's behavior?
  2. Could Ky provide an option to automatically parse error responses and make them immediately available?

Thank you for considering this enhancement. It would greatly improve the developer experience when using Ky, especially in React applications with React Query.

@yslpn yslpn changed the title Improve Error Handling in Ky to Match Axios Behavior Improve Error Handling for Better Integration with React Query Oct 6, 2024
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

No branches or pull requests

1 participant