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

Call Stack Exceeded Error in isEqual #4824

Closed
calebeby opened this issue May 16, 2019 · 4 comments · Fixed by #4924
Closed

Call Stack Exceeded Error in isEqual #4824

calebeby opened this issue May 16, 2019 · 4 comments · Fixed by #4924

Comments

@calebeby
Copy link

calebeby commented May 16, 2019

👋 Thanks for apollo, it's pretty cool

Intended outcome:

Data fetches without error

Actual outcome:

Call Stack Exceeded Error

Screen Shot 2019-05-16 at 10 59 01 AM

I did some digging into this error, and here is what I found:

isDifferentFromLastResult is called here:
https://github.com/apollographql/apollo-client/blob/master/packages/apollo-client/src/core/QueryManager.ts#L697

isEqual is called here:
https://github.com/apollographql/apollo-client/blob/master/packages/apollo-client/src/core/ObservableQuery.ts#L275

The two objects that are passed to isEqual look like this:

Screen Shot 2019-05-16 at 11 07 36 AM

a looks like:

image

b looks like:

image

When you invoke the getters on b it looks like a. Both b and a are infinitely nested:

a.allLinks[0].category.links[0] is the same object as a.allLinks[0]
b.allLinks[0].category.links[0] is the same object as b.allLinks[0]

The way isEqual is written, it does not support infinitely nested objects. This leads to the maximum call stack error because isEqual keeps calling itself with properties deeper and deeper into the infinitely nested tree.

Why is isEqual passed an infinitely nested tree? Is isEqual supposed to support infinitely nested trees?

How to reproduce the issue:

I'm not going to create a minimal reproduction quite yet, first I wanted to check and see if you had any insight based on the debugging above ☝️

Versions

  System:
    OS: macOS 10.14.2
  Binaries:
    Node: 10.11.0 - /usr/local/bin/node
    Yarn: 1.15.2 - /usr/local/bin/yarn
    npm: 6.9.0 - /usr/local/bin/npm
  Browsers:
    Chrome: 74.0.3729.131
    Firefox: 65.0
    Safari: 12.0.2

We are using @nuxtjs/apollo@4.0.0-rc4 and apollo-client@2.5.1, although I don't think the error comes from the nuxt integration. We also are using apollo-cache-inmemory@1.5.1

Any help or further guidance in debugging would be appreciated 😄

@META-DREAMER
Copy link
Contributor

Verified this issue is still present in apollo-client@2.6.0. Replacing the apollo implementation of isEqual with lodash isEqual fixes the error. Infinitely nested trees should definitely be supported.

@benjamn
Copy link
Member

benjamn commented Jun 4, 2019

This should (soon) be fixed by #4915.

@benjamn
Copy link
Member

benjamn commented Jun 4, 2019

This should now be fixed if you update to apollo-utilities@1.3.1, thanks to @capaj's PR #4915.

@benjamn benjamn closed this as completed Jun 4, 2019
@Paul-Hebert
Copy link

Awesome, thanks @benjamn , @capaj !

benjamn added a commit that referenced this issue Jun 5, 2019
Follow-up to #4915. I have kept the tests from that PR, just not the
lodash-based implementation of isEqual.

The lodash.isequal package has a ton of extra features we don't need, and
weighs in at a whopping 10KB minified (3.8KB after gzip). Very little of
that machinery is really necessary to fix #4824.

I extracted this functionality into a separate npm package called
@wry/equality, so that we have the flexibility to depend on the same logic
in other packages without importing apollo-utilities.
benjamn added a commit that referenced this issue Jun 6, 2019
Follow-up to #4915. I have kept the tests from that PR, just not the
lodash-based implementation of isEqual.

The lodash.isequal package has a ton of extra features we don't need, and
weighs in at a whopping 10KB minified (3.8KB after gzip). Very little of
that machinery is really necessary to fix #4824.

I extracted this functionality into a separate npm package called
@wry/equality, so that we have the flexibility to depend on the same logic
in other packages without importing apollo-utilities.
benjamn added a commit that referenced this issue Jun 6, 2019
* Reimplement isEqual without pulling in massive lodash.isequal.

Follow-up to #4915. I have kept the tests from that PR, just not the
lodash-based implementation of isEqual.

The lodash.isequal package has a ton of extra features we don't need, and
weighs in at a whopping 10KB minified (3.8KB after gzip). Very little of
that machinery is really necessary to fix #4824.

I extracted this functionality into a separate npm package called
@wry/equality, so that we have the flexibility to depend on the same logic
in other packages without importing apollo-utilities.

* Treat @wry/equality as an external package when bundling apollo-utilities.

* Update @wry/equality to latest version (0.1.2).

* Mention PR #4924 in CHANGELOG.md.
@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.

4 participants