Hi, I'm working with vue 2.5.3, vuex 3.0.1, apollo-client 2.0.3, apollo-link-error 1.0.1 and apollo-server-express 1.1.7
I'm trying to centralize my error handling with apollo-link-error. So when I expect a GraphQL error or a Network error, everything works great but I'm getting the following error in the console:
Uncaught (in promise) Error: GraphQL error: <<message>> at new ApolloError (ApolloError.js?d743:34)
My workflow is: the vue component calls an async function which triggers the vuex async action that calls the graphql mutation.
My code is as follows
Vue component method:
async signIn (form) {
const validForm = await this.$validator.validateAll()
if (validForm) {
await this.$store.dispatch('signIn', form)
this.$router.push('perfil')
}
}
Vuex action:
async signIn ({ commit }, signIn) {
commit('setLoading', true)
const { data } = await apolloClient.mutate({
variables: { signIn },
mutation: SIGN_IN_MUTATION
})
const { token, refreshToken } = data.signIn
localStorage.setItem('token', token)
localStorage.setItem('refresh-token', refreshToken)
commit('setLoading', false)
}
Apollo Client configuration:
import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { setContext } from 'apollo-link-context'
import { ApolloLink } from 'apollo-link'
import { onError } from 'apollo-link-error'
import store from '../store'
const requestLink = createHttpLink({
uri: 'http://localhost:3000/graphql',
credentials: 'include'
})
const errorLink = onError(({ operation, response, graphQLErrors, networkError }) => {
if (graphQLErrors) {
graphQLErrors.map(({ message, locations, path }) => {
store.commit('setErrorDialog', message)
})
}
if (networkError) {
store.commit('setErrorDialog', 'Sorry, our server is off-line. Please try again later.')
}
})
const middlewareLink = setContext(() => ({
headers: {
'x-token': localStorage.getItem('token'),
'x-refresh-token': localStorage.getItem('refresh-token')
}
}))
const afterwareLink = new ApolloLink((operation, forward) => {
const { headers } = operation.getContext()
if (headers) {
const token = headers.get('x-token')
const refreshToken = headers.get('x-refresh-token')
if (token) {
localStorage.setItem('token', token)
}
if (refreshToken) {
localStorage.setItem('refresh-token', refreshToken)
}
}
return forward(operation)
})
const link = ApolloLink.from([afterwareLink, middlewareLink, errorLink, requestLink])
const apolloClient = new ApolloClient({
link,
cache: new InMemoryCache()
})
export default apolloClient
@lobosan the onError
link doesn't stop the error from going back to Apollo Client (and thus your end components), but rather is a hook to allow you to subscribe to any network related errors to log, handle auth flow, etc.
Does that help?
Also 😍 for using Vue and Apollo together!
@jbaxleyiii thanks for your reply. Yeah make sense, so I guess it's not really possible to centralize error handling and resolve all promises inside the error link. Instead I'll do the try/catch in each of my functions that interact with graphql
Is this conclusion still valid in 2020 with the latest Apollo client? We still can't have centralized error handling? We need to handle each error on each component that issues an Apollo query individually?