Apollo-client: Possible Unhandled Promise Rejection - mutation error

Created on 30 Sep 2018  ·  4Comments  ·  Source: apollographql/apollo-client

image

On my server, i'm throwing throw new GraphQLError('whatever') and i am handeling this on the client, via Alert or rendering a component back to the user. Errors seem to be capture fine in Query components.

    <Mutation mutation={UserLikeQuery} variables={{ likeId }}>
      {(likeUser, { error, loading, data }) => {
        if (error) {
          Alert.alert('Error', 'Could not like user: ' + concatErrors(error))
        }
        return (
          <ButtonLike type="like" loading={loading} action={() => likeUser()} />
        )
      }}
    </Mutation>

Intended outcome:
Render error back to user

Actual outcome:
Renders error back to user but also throws a warning

How to reproduce the issue:
Try to Handle the error in Mutation

Versions

  System:
    OS: macOS High Sierra 10.13.6
  Binaries:
    Node: 8.12.0 - ~/.nvm/versions/node/v8.12.0/bin/node
    Yarn: 1.9.4 - /usr/local/bin/yarn
    npm: 6.4.1 - ~/.nvm/versions/node/v8.12.0/bin/npm
  Browsers:
    Chrome: 69.0.3497.100
    Safari: 11.1.2
  npmPackages:
    apollo-cache-inmemory: ^1.2.10 => 1.2.10 
    apollo-client: ^2.4.2 => 2.4.2 
    apollo-link-error: ^1.1.1 => 1.1.1 
    apollo-link-http: ^1.5.5 => 1.5.5 
    apollo-link-state: ^0.4.2 => 0.4.2 
    apollo-link-ws: ^1.0.9 => 1.0.9 
    apollo-utilities: ^1.0.21 => 1.0.21 
    react-apollo: ^2.1.0 => 2.1.11 

Most helpful comment

@farzd I was experiencing this same problem until I read the Mutation render prop https://www.apollographql.com/docs/react/essentials/mutations.html#render-prop documentation a little more.

It is not intuitive from the error handling documentation that the mutate prop passed to the render prop function, in your case the likeUser function, actually returns a promise. There are two approaches that fixed this for me. Mutation component accepts an onError prop where you can handle errors, or you can handle your error where you invoke likeUser using a catch. I chose the latter and this fixed my Jest test and prevented the error from being logged in the browser console. Something like:

<Mutation mutation={UserLikeQuery} variables={{ likeId }}>
      {(likeUser, { error, loading, data }) => {
        if (error) {
          Alert.alert('Error', 'Could not like user: ' + concatErrors(error))
        }
        return (
          <ButtonLike type="like" loading={loading} action={() => likeUser().catch(err => console.log(err))} />
        )
      }}
    </Mutation>

All 4 comments

This seems to be also causing Jest tests to error out - there's no way to catch the Promise rejection except by chaining onto mutate() as in this internal test:

https://github.com/apollographql/react-apollo/blob/62de2074fe01cde5d21dbfc582c5bb87c2011a36/test/client/Mutation.test.tsx#L438

It seems like the mutation function should _not_ be rejecting if it also going to set the error property of the the result ({data, loading, error})

any chance of anyone looking at this :) ?

@farzd I was experiencing this same problem until I read the Mutation render prop https://www.apollographql.com/docs/react/essentials/mutations.html#render-prop documentation a little more.

It is not intuitive from the error handling documentation that the mutate prop passed to the render prop function, in your case the likeUser function, actually returns a promise. There are two approaches that fixed this for me. Mutation component accepts an onError prop where you can handle errors, or you can handle your error where you invoke likeUser using a catch. I chose the latter and this fixed my Jest test and prevented the error from being logged in the browser console. Something like:

<Mutation mutation={UserLikeQuery} variables={{ likeId }}>
      {(likeUser, { error, loading, data }) => {
        if (error) {
          Alert.alert('Error', 'Could not like user: ' + concatErrors(error))
        }
        return (
          <ButtonLike type="like" loading={loading} action={() => likeUser().catch(err => console.log(err))} />
        )
      }}
    </Mutation>

Thanks @keirstaple

Was this page helpful?
0 / 5 - 0 ratings