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

Running introspection query with apollo-client results in RangeError: maximum call stack size exceeded #1717

Closed
lunedis opened this issue May 22, 2017 · 24 comments

Comments

@lunedis
Copy link

lunedis commented May 22, 2017

Intended outcome:

Running the graqhql introspection query with apollo-client. It should return the server's schema in JSON format.

import { parse, introspectionQuery} from 'graphql';
const query = parse(introspectionQuery);
client.query({query})
      .then(...)
      .catch(...);

Actual outcome:

RangeError: Maximum call stack size exceeded
    at cloneDeep (D:\Users\###\Documents\EVE\teddie\teddie-client\node_modules\apollo-client\util\cloneDeep.…:1)
    at cloneDeep (D:\Users\###\Documents\EVE\teddie\teddie-client\node_modules\apollo-client\util\cloneDeep.…:9)
    at cloneDeep (D:\Users\###\Documents\EVE\teddie\teddie-client\node_modules\apollo-client\util\cloneDeep.…:9)
    at cloneDeep (D:\Users\###\Documents\EVE\teddie\teddie-client\node_modules\apollo-client\util\cloneDeep.…:9)
...

(goes one for quite some lines)

Comment

Replacing the client.query code with networkInterface.query (not using all the fancy apollo features) works.

@helfer
Copy link
Contributor

helfer commented May 26, 2017

Hi @lunedis. 👋 I looked at the code for cloneDeep in Apollo Client, but I couldn't find an obvious reason why there would be an infinite recursion. Could you provide us with a GitHub repo that I can clone and then simply run npm install && npm test to reproduce the issue? Thanks in advance!

@helfer
Copy link
Contributor

helfer commented May 26, 2017

Actually, never mind, I think I figured out what is going on. If you're using parse from graphql, that will result in an object with circular references, which gets cloned when typenames are added (so if you initialize the client with addTypename: false you won't have the issue). If you use the gql tag, that's not the case because it doesn't include those circular references.

We should probably make our cloneDeep ignore circular references. I'd be happy to accept and merge a PR in that direction.

Finally, I just wanted to point out that I don't think Apollo Client is the right tool if you simply want to execute a query against a server and get the result. For that it makes much more sense to use the network interface directly, as you have also done, it seems 👍

@miclill
Copy link

miclill commented Jun 2, 2017

Here is how lodash solves this problem:
https://github.com/lodash/lodash/blob/master/.internal/baseClone.js#L198

@syrusakbary
Copy link

syrusakbary commented Jun 23, 2017

Also having this same issue

RangeError: Maximum call stack size exceeded
    at cloneDeep (apollo.umd.js:1276)
    at cloneDeep (apollo.umd.js:1284)
    at cloneDeep (apollo.umd.js:1284)
    at cloneDeep (apollo.umd.js:1284)
    at cloneDeep (apollo.umd.js:1284)
    at cloneDeep (apollo.umd.js:1284)
    at cloneDeep (apollo.umd.js:1284)
    at cloneDeep (apollo.umd.js:1284)
    at cloneDeep (apollo.umd.js:1284)
    at cloneDeep (apollo.umd.js:1284)
    at cloneDeep (apollo.umd.js:1284)
    at cloneDeep (apollo.umd.js:1284)
    at cloneDeep (apollo.umd.js:1284)
    at cloneDeep (apollo.umd.js:1284)
    at cloneDeep (apollo.umd.js:1284)
    at cloneDeep (apollo.umd.js:1284)
    at cloneDeep (apollo.umd.js:1284)
    at cloneDeep (apollo.umd.js:1284)
    at cloneDeep (apollo.umd.js:1284)
    at cloneDeep (apollo.umd.js:1284)
    at cloneDeep (apollo.umd.js:1284)
    at cloneDeep (apollo.umd.js:1284)

Any idea when this could be fixed?
We got this triggered in a very special edge-case.

@stale
Copy link

stale bot commented Aug 7, 2017

This issue has been automatically marked as stale becuase it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions to Apollo Client!

@seeden
Copy link
Contributor

seeden commented Aug 18, 2017

I have same problem with all queries via react-apollo.
I can simulate it very easily. Try to turn off your server during the query and you will see frozen browser and after one/few minutes a lot of errors.
@helfer set addTypename to false is not a very good solution :)

@yannickschuchmann
Copy link

I can confirm what @seeden says. If server is not available react-apollo goes crazy firingAPOLLO_QUERY_INITand APOLLO_QUERY_STOP which ends up in an app crash on react-native.

@stale
Copy link

stale bot commented Sep 17, 2017

This issue has been automatically marked as stale becuase it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions to Apollo Client!

@seeden
Copy link
Contributor

seeden commented Sep 18, 2017

any update from apollo team?

@volkanunsal
Copy link

Would be great to have a solution for this. addTypename: false trick doesn't work for me.

@stale
Copy link

stale bot commented Oct 11, 2017

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions to Apollo Client!

@stale
Copy link

stale bot commented Oct 25, 2017

This issue has been automatically closed because it has not had recent activity after being marked as stale. If you belive this issue is still a problem or should be reopened, please reopen it! Thank you for your contributions to Apollo Client!

@stale stale bot closed this as completed Oct 25, 2017
@KaroseLiu
Copy link

@seeden how to solve the problem, add the 'addTypename: false' not work.

@seeden
Copy link
Contributor

seeden commented Nov 17, 2017

I did not solve it. I have this issue still in my project

@seeden
Copy link
Contributor

seeden commented Dec 8, 2017

@jbaxleyiii can you reopen this issue?

I am not able to download introspection with latest apollo-client

import 'isomorphic-fetch';
import { parse, introspectionQuery } from 'graphql';
import { InMemoryCache } from 'apollo-cache-inmemory';
import ApolloClient from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { graphql } from '../config/client';

const link = new HttpLink({
  uri: graphql.url,
  credentials: 'same-origin',
});
const cache = new InMemoryCache({});

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

const query = parse(introspectionQuery);

client
  .query({ query })
  .then((result) => {
    console.log(JSON.stringify(result, null, '  '));
  })
  .catch((err) => {
    console.error(err);
  });

I will always get

RangeError: Maximum call stack size exceeded
    at cloneDeep (/Users/seeden/Documents/git/node_modules/apollo-utilities/lib/util/cloneDeep.js:1:26)
    at cloneDeep (/Users/seeden/Documents/git/node_modules/apollo-utilities/lib/util/cloneDeep.js:9:34)
    at cloneDeep (/Users/seeden/Documents/git/node_modules/apollo-utilities/lib/util/cloneDeep.js:9:34)
    at cloneDeep (/Users/seeden/Documents/git/node_modules/apollo-utilities/lib/util/cloneDeep.js:9:34)
    at cloneDeep (/Users/seeden/Documents/git/node_modules/apollo-utilities/lib/util/cloneDeep.js:9:34)
    at cloneDeep (/Users/seeden/Documents/git/node_modules/apollo-utilities/lib/util/cloneDeep.js:9:34)
    at cloneDeep (/Users/seeden/Documents/git/node_modules/apollo-utilities/lib/util/cloneDeep.js:9:34)
    at cloneDeep (/Users/seeden/Documents/git/node_modules/apollo-utilities/lib/util/cloneDeep.js:9:34)
    at cloneDeep (/Users/seeden/Documents/git/node_modules/apollo-utilities/lib/util/cloneDeep.js:9:34)
    at cloneDeep (/Users/seeden/Documents/git/node_modules/apollo-utilities/lib/util/cloneDeep.js:9:34)

versions:

    "apollo-cache-inmemory": "^1.1.2",
    "apollo-client": "^2.1.0",
    "apollo-link": "^1.0.5",
    "apollo-link-batch-http": "^1.0.2",
    "apollo-link-dedup": "1.0.0",
    "apollo-link-http": "^1.3.0",
    "apollo-link-retry": "^1.0.2",
    "apollo-link-ws": "^1.0.2",
    "apollo-utilities": "^1.0.3",

@FezVrasta
Copy link

I'm experiencing the same, would you consider a PR that replaces the custom cloneDeep with the standalone version from Lodash?

@drew24
Copy link

drew24 commented Jan 9, 2018

Having this issue as well, would be much appreciated if a solution was given

addTypename: false

Did not work for me
@helfer

@seeden
Copy link
Contributor

seeden commented Jan 10, 2018

addTypename: false is really bad idea because apollo needs to have it. I am looking different solution.

@thachp
Copy link

thachp commented Feb 6, 2018

I'm still able to reproduce.

├─┬ apollo-client-preset@1.0.8
│ ├─┬ apollo-cache-inmemory@1.1.7
│ │ ├─┬ apollo-cache@1.1.2
│ │ │ └── apollo-utilities@1.0.6
│ │ ├── apollo-utilities@1.0.6
│ │ └─┬ graphql-anywhere@4.1.3
│ │ └── apollo-utilities@1.0.6
│ ├─┬ apollo-client@2.2.2
│ │ ├── @types/async@2.0.47
│ │ ├─┬ apollo-link-dedup@1.0.5
│ │ │ └── apollo-link@1.0.7
│ │ ├── apollo-utilities@1.0.6
│ │ └── zen-observable@0.7.1
│ ├── apollo-link@1.0.7
│ └─┬ apollo-link-http@1.3.2
│ └── apollo-link@1.0.7
├─┬ graphql@0.11.7
│ └── iterall@1.1.3
└── graphql-tag@2.6.1

@jbaxleyiii can you reopen this issue?

@peisenmann
Copy link

peisenmann commented Feb 15, 2018

Still reproduceable

import 'isomorphic-fetch'

import {parse} from 'graphql/language/parser'
import {introspectionQuery} from 'graphql/utilities/introspectionQuery'

import {ApolloClient} from 'apollo-client'
import {createHttpLink} from 'apollo-link-http'
import {InMemoryCache} from 'apollo-cache-inmemory'

const GRAPHQL_URL = 'http://localhost:8000/graphql'


const query = parse(introspectionQuery)
const link = createHttpLink({uri: GRAPHQL_URL})
const cache = new InMemoryCache({addTypename: true})

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

client.query({ query }).then((result) => {
  console.log(JSON.stringify(result, null, '  '))
}).catch((err) => console.error(err))

In fact, blows up with addTypename: false, too.

@josepmorey
Copy link

any solution?? We have same issue...

@slycoder
Copy link

As pointed out above, this is happening because parse creates an object with circular references. These references are only in the location fields of the resulting object so I don't think they're actually needed. So you can try:

parse(your_query, { noLocation: true })

and see if that works for you.

@kibin
Copy link

kibin commented Aug 28, 2018

@slycoder thanks! Your solution helped

@hwillson hwillson added to do and removed to do labels Sep 4, 2018
hwillson added a commit that referenced this issue Sep 4, 2018
The custom `cloneDeep` function we're using in the
`apollo-utilities` package doesn't handle circular references
well (as in it crashes if it hits one). These changes replace
the custom `cloneDeep` implementation with `fclone`, which is
a dependency free, lightweight and performant deep clone
implementation. `fclone` drops circular references
(replacing them with a `[Circular]` string).

Fixes #1717.
@hwillson hwillson self-assigned this Sep 4, 2018
@hwillson
Copy link
Member

hwillson commented Sep 4, 2018

#3881 should help address this - thanks!

hwillson added a commit that referenced this issue Sep 4, 2018
* Replace custom `cloneDeep` function

The custom `cloneDeep` function we're using in the
`apollo-utilities` package doesn't handle circular references
well (as in it crashes if it hits one). These changes replace
the custom `cloneDeep` implementation with `fclone`, which is
a dependency free, lightweight and performant deep clone
implementation. `fclone` drops circular references
(replacing them with a `[Circular]` string).

Fixes #1717.

* Changelog update
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.