最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Show Apollo mutation error to user in Vue.js? - Stack Overflow

programmeradmin2浏览0评论

I am using Vue.js with Vue-Apollo and initiating a User mutation to sign in a user. I am using the graph.cool service.

I have a request pipeline function setup to catch some errors, like an invalid email.

When the request is made with bad / invalid input, my error catch() fires (as expected) and in the network tab I can see the JSON for the custom errors messages. But how do I access these errors / response from within the catch if an error is triggered from graph.cool?

Example:

signin () {
  const email = this.email
  const password = this.password

  this.$apollo.mutate({
    mutation: signinMutation,
    variables: {
      email,
      password
    }
  })
  .then((data) => {
    // This never fires on an error, so I can't 
    // show the user the errors in the network repsonse.
    console.log(data) 
  })
  .catch((error) => {
    // Error in this part fires in the console 
    // but I'm unable to show the JSON response 
    // errors because the 'then()' above doesn't execute.
    console.error(error)
  })
}

I get the following error for an unrecognised user:

Error: GraphQL error: No user found with that information at new ApolloError (eval at (app.js:956), :34:28) at eval (eval at (app.js:1353), :139:33) at

Any idea how to show the errors in the response from within the catch()?

I can literally see the errors I want to show to the user in the response on the network tab here:

...but I can't figure out how to do it.

Any help much appreciated! Thank you.

I am using Vue.js with Vue-Apollo and initiating a User mutation to sign in a user. I am using the graph.cool service.

I have a request pipeline function setup to catch some errors, like an invalid email.

When the request is made with bad / invalid input, my error catch() fires (as expected) and in the network tab I can see the JSON for the custom errors messages. But how do I access these errors / response from within the catch if an error is triggered from graph.cool?

Example:

signin () {
  const email = this.email
  const password = this.password

  this.$apollo.mutate({
    mutation: signinMutation,
    variables: {
      email,
      password
    }
  })
  .then((data) => {
    // This never fires on an error, so I can't 
    // show the user the errors in the network repsonse.
    console.log(data) 
  })
  .catch((error) => {
    // Error in this part fires in the console 
    // but I'm unable to show the JSON response 
    // errors because the 'then()' above doesn't execute.
    console.error(error)
  })
}

I get the following error for an unrecognised user:

Error: GraphQL error: No user found with that information at new ApolloError (eval at (app.js:956), :34:28) at eval (eval at (app.js:1353), :139:33) at

Any idea how to show the errors in the response from within the catch()?

I can literally see the errors I want to show to the user in the response on the network tab here:

...but I can't figure out how to do it.

Any help much appreciated! Thank you.

Share Improve this question asked Jul 19, 2017 at 19:20 Michael Giovanni PumoMichael Giovanni Pumo 14.8k18 gold badges100 silver badges145 bronze badges 2
  • I think you can add another .then after the .catch: stackoverflow./questions/35999072/… – thanksd Commented Jul 19, 2017 at 19:26
  • Whilst that's true, I can't get hold of the 'data' in the actual response itself. :( – Michael Giovanni Pumo Commented Jul 19, 2017 at 19:34
Add a ment  | 

2 Answers 2

Reset to default 7

So, it looks as though I was handling this the wrong way by barking up the wrong tree.

The key to the answer was examining the error from the .catch() with console.dir(error). This revealed some useful keys...namely:

error.graphQLErrors[0]

So all in all, the corrected code looks like this:

signin () {
  const email = this.email
  const password = this.password

  this.$apollo.mutate({
    mutation: signinMutation,
    variables: {
      email,
      password
    }
  })
  .then(data => {
    console.log(data)
  })
  .catch(error => {
    console.log(graphQLErrorMessages(error))
  })
}

The graphQLErrorMessages() function is a helper I wrote, so that I can reuse this in other .catch() blocks:

function graphQLErrorMessages (errorsFromCatch) {
  const errors = errorsFromCatch.graphQLErrors[0]
  const messages = []

  if (errors.hasOwnProperty('functionError')) {
    const customErrors = JSON.parse(errors.functionError)
    messages.push(...customErrors.errors)
  } else {
    messages.push(errors.message)
  }

  return messages
}

It returns an array of error messages (which is what I needed) but you could format this any way you like.

It might be a little https://graph.cool specific in its logic (I'm not so sure), but I hope this ends up helping someone also stuck in a similar situation!

I may be misunderstanding your question so please ment and correct me if I am but it looks like you may be having trouble with Promises more than with Vue or GraphQL.

Just like in a try...catch statement, once you catch an error, your program will continue to execute unless you re-throw the error. For example:

This Catches

try { 
  codeThatThrowsAnError();
} catch(e) {
  // Do Nothing
}

This re-throws

try { 
  codeThatThrowsAnError();
} catch(e) {
  throw new Error("Err 135: I failed")
}

Similarly, in Promise land, you can either catch the error and move like you have in your example, or you can re-throw. What you may be missing is that anything you return from a catch statement will be used in the next then. For example:

somethingReturningAFailedPromise()
  .then(doWork)
  .catch((err) => {
    return "I'm a New Value"
  })
  .then(console.log)

//=> "I'm a New Value"

It sounds to me like what you need is a data function that is more resilient to failure like the following:

const getUserProfile = (id) => {
  return fetchUserData(id)
    .catch((err) => {
      logError(err);
      return {};
    })
}
发布评论

评论列表(0)

  1. 暂无评论