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

How to catch mutation errors from the server #1496

Closed
kojuka opened this issue Mar 26, 2017 · 15 comments
Closed

How to catch mutation errors from the server #1496

kojuka opened this issue Mar 26, 2017 · 15 comments

Comments

@kojuka
Copy link

kojuka commented Mar 26, 2017

I’ve got a question about error handling client side.

My server returns this on validation error:

{
  "data": {
    "auth": null
  },
  "errors": [
    {
      "message": "An authentication error has occurred",
      "name": "AuthenticationError",
      "time_thrown": "2017-03-26T01:26:50.439Z",
      "data": {
        "errors": {
          "login": "Authentication failed.  Invalid email or password"
        }
      }
    }
  ]
}

I’d like to get access to the validation errors using apollo-client mutation - something like this:

    return auth(values)  //<— this is a mutation
      .then(({data}) => {
        loginThenRedirect(data); // <--- log user in
      })
      .catch((mutationErrors) => {
        const {errors} = mutationErrors.data  // <--- doesn't work
        this.setState({errors})  // <— display the errors
      });

But mutationErrors get swallowed up and only show a string Error: GraphQL error: An authentication error has occurred…

Is there a way to get the contents of the server error so I can display it client side?

@helfer
Copy link
Contributor

helfer commented Mar 28, 2017

@webular I think it might not be possible at the moment. It should be pretty easy to fix with a PR though, I think.

cc @cesarsolorzano do you think it's feasible?

@helfer
Copy link
Contributor

helfer commented Mar 28, 2017

@webular can you try this with mutationError.graphQLErrors[0].data?

If that doesn't work, please print JSON.stringify(mutationError) and then paste the output here.

Thanks!

@baptistemanson
Copy link

If your server returns something different than 200 response (like a 401 Unauthorized), we found the error buried in "networkErrors".
What we did was:

const getNetworkErrors = error => error.networkError.response.json().then(e => e.errors.map(e => e.message).join(','))

return auth(values)  //<— this is a mutation
      .then(({data}) => {
        loginThenRedirect(data); // <--- log user in
      })
      .catch(error => {
        if (error.networkError) {
          getNetworkErrors(error).then(console.log)
        } else {
          console.log(error.message)
        }
      });

We use yarn add stringify to discover the structure of errors.

@kojuka
Copy link
Author

kojuka commented Mar 30, 2017

@helfer Ok that worked out.

I was able to get the error object by doing
const error = JSON.parse(JSON.stringify(mutationError))

not sure if there is a better way to turn the string into an object but this works for me.

Thank you all for the help!

@variousauthors
Copy link

When I catch the error from a mutation like this,

.catch((e) => { console.log(e) })

The following message is logged to the console,

Error: GraphQL error: Unauthorized
    at new ApolloError (ApolloError.js:32)
    at QueryManager.js:119
    at <anonymous>

So I got the impression that this issue was still occurring.

When I inspected the object more closely, like this,

.catch((e) => { console.log(e.graphQLErrors) })

It logged an array of error objects.

So the problem was my expectations, not the object itself. Just putting this here for posterity, in case anyone else is caught off-guard by this behaviour.

@tgdn
Copy link

tgdn commented Sep 22, 2017

Got the same, and it doesn't seem to be documented

@vladinator1000
Copy link

vladinator1000 commented Oct 11, 2017

Is it a good idea to catch user-specific errors like "wrong email or password", using apollo-errors? I'm trying to figure out how to update the store on a catch.

@gorjanz
Copy link

gorjanz commented Nov 30, 2017

Using:
apollo-server-express:1.2.0 and apollo-client:1.8.1
performing
.catch(e => ...) on a mutation call
I get:

"GraphQL error: 500 - {"timestamp":1512048932621,"status":500,"error":"Internal Server Error","exception":"java.lang.IllegalArgumentException","message":"Class name 'g1-test-2' and grade '2' already exists for this school","path":"/api/school-class/"}"

Is there a nice way to get just the message? Other than doing .substring() and then JSON.parse("{"timestamp...}")

@tgdn
Copy link

tgdn commented Nov 30, 2017

@gorjanz Have you tried .catch((e) => { console.log(e.graphQLErrors) }) ?

@gorjanz
Copy link

gorjanz commented Nov 30, 2017

@tgdn yes, it prints an array with objects, with one of the keys being the message I printed above.

@webmobiles
Copy link

@gorjanz I'm having problems with graphql-server-express , so this is outdated ? i have some problems with catch errors with that ; must I migrate to apollo-server-express ?

@miguelocarvajal
Copy link
Contributor

Am experiencing a similar issue with graphql-java backend. Cannot access the errors within the catch.

e.graphQLErrors is undefined.

Maybe its the response sent back by the server? Does anybody know what that data is supposed to look like?

@TheRusskiy
Copy link

Hope this helps someone:
if server returns error code >= 400 then graphqlErrors on error object is empty, so responses above are not helpful.
If you try to read them like @baptistemanson suggested it's also not gonna work because the body stream was already read from.
To get errors in this case you need to error.networkError.result.errors.

@felixiho
Copy link

Hope this helps someone:
if server returns error code >= 400 then graphqlErrors on error object is empty, so responses above are not helpful.
If you try to read them like @baptistemanson suggested it's also not gonna work because the body stream was already read from.
To get errors in this case you need to error.networkError.result.errors.

This just saved my day. Thank you @TheRusskiy

@bitQ2019
Copy link

For me, It is because of some of my packages relays on node.js which clearly not on mobile.
I installed the
node-libs-react-native and solved the problem

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests