Apollo-link: Uncaught (in promise) Error: GraphQL error

Created on 22 Nov 2017  ·  3Comments  ·  Source: apollographql/apollo-link

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

All 3 comments

@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?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

steffenmllr picture steffenmllr  ·  4Comments

roupen picture roupen  ·  6Comments

j3ddesign picture j3ddesign  ·  3Comments

valerybugakov picture valerybugakov  ·  5Comments

ChenRoth picture ChenRoth  ·  4Comments