question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Testing Error State of Mutation is throwing Global Error

See original GitHub issue

I want to reopen https://github.com/apollographql/react-apollo/issues/2614 from the old repo as I ran into the exact same Issue today with @apollo/client": "3.2.2.

I have a component that uses the useMutation hook and renders differently when useMutation returns an error

export const DELETE_DOG_MUTATION = gql`
  mutation deleteDog($name: String!) {
    deleteDog(name: $name) {
      id
      name
      breed
    }
  }
`;

export function DeleteButton() {
  const [mutate, { loading, error, data }] = useMutation(DELETE_DOG_MUTATION);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error!</p>;
  if (data) return <p>Deleted!</p>;

  return (
    <button onClick={() => mutate({ variables: { name: 'Buck' } })}>
      Click me to Delete Buck!
    </button>
  );
}

I want to Test this behaviour as described in the Docs

it('should show error UI', async () => {
  const deleteDog = { name: 'Buck', breed: 'Poodle', id: 1 };
  const mocks = [
    {
      request: {
        query: DELETE_DOG_MUTATION,
        variables: { name: 'Buck' },
      },
      error: new Error('aw shucks'),
    },
  ];

  const component = renderer.create(
    <MockedProvider mocks={mocks} addTypename={false}>
      <DeleteButton />
    </MockedProvider>,
  );

  // find the button and simulate a click
  const button = component.root.findByType('button');
  button.props.onClick(); // fires the mutation

  await new Promise(resolve => setTimeout(resolve, 0)); // wait for response

  const tree = component.toJSON();
  expect(tree.children).toContain('Error!');
});

Intended outcome:

The Test should pass without throwing an error.

Actual outcome:

Passing mocks with an Error to <MockedProvider /> does actually throw a global Error

    aw shucks

      at new ApolloError (node_modules/@apollo/client/errors/index.js:26:28)
      at Object.error (node_modules/@apollo/client/core/QueryManager.js:146:48)
      at notifySubscription (node_modules/zen-observable/lib/Observable.js:140:18)
      at onNotify (node_modules/zen-observable/lib/Observable.js:179:3)
      at SubscriptionObserver.error (node_modules/zen-observable/lib/Observable.js:240:7)
      at node_modules/@apollo/client/utilities/observables/iteration.js:4:68
          at Array.forEach (<anonymous>)
      at iterateObserversSafely (node_modules/@apollo/client/utilities/observables/iteration.js:4:25)
      at Object.error (node_modules/@apollo/client/utilities/observables/Concast.js:33:21)
      at notifySubscription (node_modules/zen-observable/lib/Observable.js:140:18)

I figured out that when I add an onError option to useMutation my test runs as expected but I guess this is just a workaround.

  const [mutate, { loading, error, data }] = useMutation(DELETE_DOG_MUTATION, {onError: () => {}});

How to reproduce the issue:

I cant share the code of the application I am working on but I can try to create a Codesandbox if neccessary but I hope my explanation is detailed enough.

Versions System: OS: macOS Mojave 10.14.6 Binaries: Node: 10.16.0 - /usr/local/bin/node npm: 6.11.2 - /usr/local/bin/npm Browsers: Chrome: 86.0.4240.80 Firefox: 81.0.1 Safari: 12.1.2 npmPackages: @apollo/client: ^3.2.2 => 3.2.2 “jest”: “^24.9.0”,

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:16
  • Comments:11 (2 by maintainers)

github_iconTop GitHub Comments

8reactions
markcnunescommented, May 26, 2021

This comment managed to get around it using errorPolicy:

<MockedProvider
  mocks={mocks}
  addTypename={false}
  defaultOptions={{
    mutate: {
      errorPolicy: 'all'
    }
  }}
>

You can then target to find the element rendered by if (error) return <p>Error!</p>;

4reactions
leepowelldevcommented, Oct 2, 2021

Just got bitten by this … wasted a couple of hours. If there’s no appetite to change behaviour by the Apollo team, then this behaviour really needs to be highlighted in the documentation. I guess my expectation was any errors would be passed back in the error property, without ALSO throwing.

Seems the best way to handle this is by adding a empty onError handler in the options in any useQuery or useMutation - but it would be great if there was an option to suppress the error also being thrown and just handle it in the error property if needed.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Handling operation errors - Apollo GraphQL Docs
Apollo Client can encounter a variety of errors when executing operations on your GraphQL server. Apollo Client helps you handle these errors according...
Read more >
Jest & Apollo Client: testing mutation error states
Apollo's MockProvider is a great tool for testing mutations, however it's a little bit magical, making errors a little difficult to find.
Read more >
Handling errors with react-apollo useMutation hook
Having error state like this can be useful when you want your UI to reflect the fact there's an error. For example, you...
Read more >
useMutation | TanStack Query Docs
useMutation · Defaults to the global query config's useErrorBoundary value, which is undefined · Set this to true if you want mutation errors...
Read more >
Error Handling | Redux Toolkit
If your query or mutation happens to throw an error when using fetchBaseQuery, it will be returned in the error property of the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found