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

useLazyQuery throws instead of returning with error #9669

Closed
Tracked by #9684
alexandergottlieb opened this issue May 4, 2022 · 4 comments · Fixed by #9684
Closed
Tracked by #9684

useLazyQuery throws instead of returning with error #9669

alexandergottlieb opened this issue May 4, 2022 · 4 comments · Fixed by #9684

Comments

@alexandergottlieb
Copy link

Intended outcome:

When useLazyQuery encounters an error, I would expect it to return a QueryResult with error populated, just like useQuery.

This should work:

const [execute] = useLazyQuery(...);
const { error } = await execute();
if (error) {
  ...
}

Actual outcome:

useLazyQuery throws, so the if (error) clause is unreachable.

How to reproduce the issue:

Sandbox: https://codesandbox.io/s/uselazyquery-error-3224g3?file=/src/test.spec.js

import { render, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { gql, useLazyQuery, useQuery } from "@apollo/client";
import { MockedProvider } from "@apollo/client/testing";

const FOO_QUERY = gql`
  query GetFoo {
    foo {
      bar
    }
  }
`;

const mocks = [
  {
    request: {
      query: FOO_QUERY
    },
    error: new Error("A network error")
  }
];

const NormalQuery = ({ onError }) => {
  const { error } = useQuery(FOO_QUERY);
  if (error) onError();
  return null;
};

const LazyQueryButton = ({ onError }) => {
  const [executeQuery] = useLazyQuery(FOO_QUERY);
  const handleClick = async () => {
    try {
      const { error } = await executeQuery();
      // Unreachable
      if (error) onError();
    } catch (e) {
      // We end up here
    }
  };
  return <button onClick={handleClick}>Click me</button>;
};

// Passes
test("useQuery returns error", async () => {
  const handleErrorMock = jest.fn();
  render(
    <MockedProvider mocks={mocks}>
      <NormalQuery onError={handleErrorMock} />
    </MockedProvider>
  );
  await waitFor(() => {
    expect(handleErrorMock).toHaveBeenCalled();
  });
});

// Fails
test("useLazyQuery returns error", async () => {
  const handleErrorMock = jest.fn();
  render(
    <MockedProvider mocks={mocks}>
      <LazyQueryButton onError={handleErrorMock} />
    </MockedProvider>
  );
  const button = screen.getByRole("button");
  userEvent.click(button);
  await waitFor(() => {
    expect(handleErrorMock).toHaveBeenCalled();
  });
});

Versions

  System:
    OS: macOS 10.15.7
  Binaries:
    Node: 14.18.3
    Yarn: 1.22.10
    npm: 6.14.15
  npmPackages:
    @apollo/client: ^3.6.2 => 3.6.2 
    apollo: ^2.33.9 => 2.33.9
@alexandergottlieb alexandergottlieb changed the title useLazyQuery throws instead of returning a promise with error useLazyQuery throws instead of returning with error May 4, 2022
@benjamn benjamn self-assigned this May 4, 2022
@benjamn benjamn added this to the v3.6.x patch releases milestone May 4, 2022
benjamn added a commit that referenced this issue May 5, 2022
As a side effect of not throwing any ApolloError objects (see removed
code), this commit also fixes issue #9669.
@benjamn
Copy link
Member

benjamn commented May 5, 2022

@alexandergottlieb This should be fixed if you run npm i @apollo/client@next (to get version 3.6.3). Thanks for reporting this issue, instead of assuming it was an intended change in behavior!

@alexandergottlieb
Copy link
Author

Thanks @benjamn for the quick fix!

@pumuckelo
Copy link

Hello @benjamn

I think we have the same issue on useMutation here
Can you confirm?

@benjamn
Copy link
Member

benjamn commented May 25, 2022

I think you're right @pumuckelo—throwing/rejecting makes everything trickier, and potentially discards information about result.data that was also delivered.

In other words, what I said in #9142 (comment) and PR #9684 applies to client.mutate and useMutation as well.

I've assigned issue #9065 to myself and added it to the v3.6.x patch releases milestone. Thanks!

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 1, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
3 participants