apollo-client icon indicating copy to clipboard operation
apollo-client copied to clipboard

graphQLErrors is empty in promise chain

Open mydearxym opened this issue 7 years ago • 27 comments

i am using [email protected] standalone with the basic setup:

const graphLink = new HttpLink({ uri: 'http://localhost:4001/graphiql' })

const errorLink = onError(({ graphQLErrors }) => {
  if (graphQLErrors) {
    graphQLErrors.map(
      ({ message, path, detail }) =>
      >  graphQLErrors has value here
        debug(`[GraphQL error-- ]: ${path} ${message} ${detail}`)
    )
  }
})

const link = ApolloLink.from([errorLink, graphLink])

const client = new ApolloClient({
  link,
  cache: new InMemoryCache(),
})

the graphQLErrors result in onError block is right. this is the grahql-playground result:

image

but the graphQLErrors is empty in the promise-catch block

const QUERY = `
{
  allUsers2 {
    entries {
      username
    }
    totalCount
    pageSiz
  }
}
`
const query = gql`
    ${QUERY}
  `

  client
    .query({
      query,
      context,
    })
    .then(data => {
      debug(data)
    })
    .catch(({ graphQLErrors, message }) => {
      if (graphQLErrors) {
    >   graphQLErrors is Empty here 
        /* debug('【catch graphQLErrors:】 ', graphQLErrors) */
      }
    })

mydearxym avatar Jan 03 '18 09:01 mydearxym

I'm having the same issue of graphQLErrors being empty, even though the server response has one or more errors in it.

My code, unchanged, worked as expected before upgrading to Apollo v2 from v1. So some change in v2 is preventing graphQLErrors from being populated like it was in v1, and I can't figure what that is. This has broken all of the error handling in my application :/

dizlexik avatar Feb 08 '18 16:02 dizlexik

I'm having the same issue as this. Any updates? It looks like the error exists in the networkErrors but not in the graphQLErrors.

KevinHewson avatar Mar 29 '18 20:03 KevinHewson

any updates?

Mati365 avatar Jul 02 '18 09:07 Mati365

I found simple fix: err.networkError.result.errors, invoking it in catch() handlers will fix problem

Mati365 avatar Jul 02 '18 09:07 Mati365

any updates?

@Mati365 the error should be in graphQLErrors, in my case if the error is from the resolver graphQLErrors is not empty but when the error come from apollo-server-express context the error is in networkError. and graphQLErrors is empty!

That does not make sense and I don't want to handle 2 cases in my catch statement!

mi-mazouz avatar Oct 23 '18 15:10 mi-mazouz

I'm also seeing this issue. My server returns a 400 response that looks like:

{
  "errors":[
    {"message":"Invalid email or password."}
  ],
  "data":{"logIn":null}
}

The onError middleware correctly passes this through in the graphQLErrors array (along with a networkError), but by the time it gets to the Mutation component's error object, graphQLErrors is an empty array. The err.networkError.result.errors trick works but is hacky. Any thoughts?

pfarnach avatar Jun 07 '19 17:06 pfarnach

Thanks for reporting this. There hasn't been any activity here in quite some time, so we'll close this issue for now. If this is still a problem (using a modern version of Apollo Client), please let us know. Thanks!

jbaxleyiii avatar Jul 09 '19 20:07 jbaxleyiii

I just posted last month and it's still a problem. I don't think this issue should be closed.

pfarnach avatar Jul 09 '19 20:07 pfarnach

+1 problem is still here

cybernetlab avatar Jul 30 '19 13:07 cybernetlab

+1 please re-open, still seeing this behavior in latest the version

patpaev avatar Oct 03 '19 03:10 patpaev

I too am experiencing this problem today All the errors returned from GQL are populated in the networkError property as opposed to the graphQLErrors array when using a mutation.

Edit: I am now extracting errors with some custom functions

import {get} from 'lodash'

export async function extractFirstError(e) {
    const errorPaths = [
        'graphQLErrors[0].message',
        'networkError.result.errors[0].message',
        'response.errors[0].message',
        'message'
    ]
    const path = errorPaths.find(path => get(e, path))
    return get(e, path)
}

export async function extractErrors(e) {
    const errors = []
    const errorPaths = [
        'graphQLErrors',
        'networkError.result.errors',
        'response.errors'
    ]
    const paths = errorPaths.filter(path => get(e, path))
    paths.forEach(path => errors.push(...get(e, path)))
    return errors ? errors : [e]
}

ThisIsRuddy avatar Oct 03 '19 16:10 ThisIsRuddy

I have still the same problem...

  • "apollo-boost": "^0.4.7", -"@apollo/react-hooks": "^3.1.3", why it is closed???!!!

amirqasemi74 avatar Mar 06 '20 19:03 amirqasemi74

I'm also running into this. Should a new issue be opened?

SachaG avatar Apr 28 '20 08:04 SachaG

any updates on this?

cmnstmntmn avatar Jun 13 '20 14:06 cmnstmntmn

Having this same problem still with v2.6.10

autumnwoodberry avatar Jul 01 '20 18:07 autumnwoodberry

Unfortunately 95% of the Github issue emails I get are from people like me running into issues with this library. You may consider using a different tool like urql or writing raw GraphQL queries/mutations paired with something like react-query to handle caching and request state.

pfarnach avatar Jul 01 '20 19:07 pfarnach

@pfarnach Totally agree, using plain simple fetch() for GQL queries is still less irritating than fighting with many abonated bugs like it in this piece of shit

Mati365 avatar Jul 01 '20 19:07 Mati365

@apollo/[email protected]

graphQLErrors array is empty, but networkError.result.errors has GraphQL errors.

After a bit of further reading... (https://www.apollographql.com/blog/full-stack-error-handling-with-graphql-apollo-5c12da407210)

A graphQLError is an error that occurs in a resolver, a networkError happens outside a resolver:

For example, the client failed to connect to your GraphQL endpoint, or some error occurred within your request middleware, or there was an error in the parse/validation phase of your query.

By that definition I don't have a bug, but perhaps renaming the fields might help make this less of a foot gun? Maybe rename graphQLErrors to resolverErrors so that (for those of us who don't read all the docs) we don't mistake parsing/validation errors for resolver errors.

earnubs avatar Jul 06 '20 13:07 earnubs

Thanks for reporting this. There hasn't been any activity here in quite some time, so we'll close this issue for now. If this is still a problem (using a modern version of Apollo Client), please let us know. Thanks!

this error still exists in 2021, why??? image

liho00 avatar May 19 '21 15:05 liho00

I still have this problem please fix this problem.

saanny avatar Jul 24 '21 02:07 saanny

+1 unfortunately, problem is still here

hdsand avatar Aug 02 '21 14:08 hdsand

why it is closed? still empty graphQLErrors array from hook in 2k22 :)

NikolaZh avatar Jun 30 '22 15:06 NikolaZh

4 years have passed, bug still exists :)

marhub avatar Sep 22 '22 13:09 marhub

@marhub and it will exist forever because maintainers seem to ignore bug reports (meanwhile focusing on creating new features with breaking changes)

Mati365 avatar Sep 23 '22 06:09 Mati365

@jbaxleyiii this is still a problem

kinda-neat avatar Dec 28 '22 08:12 kinda-neat

This problem is still there. Edit: Switching to react-query fixed the issue

rajatbarman avatar May 08 '23 09:05 rajatbarman

It's now over 6 years since the first report. Any news on this problem?

Lemonify avatar Apr 16 '24 20:04 Lemonify

If this is of any help, I'm just collecting the errors from networkError.result as explained in earlier threads and this still works in the latest version (I tested it with v3.13.6). Here is the code I'm using:

import { ApolloError } from '@apollo/client';
import { GraphQLFormattedError } from 'graphql';

export function getGraphQLErrors(error?: ApolloError) {
  const errors: GraphQLFormattedError[] = [];

  if (error?.graphQLErrors) {
    errors.push(...error.graphQLErrors);
  }

  if (error?.networkError && 'result' in error.networkError && typeof error.networkError.result === 'object') {
    errors.push(...error.networkError.result.errors);
  }

  return errors;
}

hbj avatar Apr 08 '25 09:04 hbj

In the upcoming Apollo Client 4.0, we will be changing error handling in general, so this will no longer be a problem. It has already changed almost everywhere in the alphas that are out now, and onError is the last thing we will need to tackle - this will be done in #12423.

So please follow along and try the alphas - we're looking forward to feedback.

phryneas avatar Apr 08 '25 09:04 phryneas