marmelab / marmelab/react-admin

[ra-data-graphql] Circular reference of entity nested in object/array provokes "Maximum call stack size exceeded" upon introspection

Open
#8,734 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
26.9k
Forks
5.5k
Avg merge
2d 3h
Merged PRs (30d)
19

Description

type User {
  _id: String!
  bookmark: Bookmark # Works just fine
  bookmarks: [Bookmark!]! # Provoke a "Maximum call stack size exceeded" Error
  stuffs: [Stuff!]
}

type Bookmark {
  book: Book! # ResolveField
  bookId: String!
}

type Book {
  _id: String!
  author: User! # ResolveField
  authorId: String!
}

type Stuff {
  bookmark: Bookmark! # Provoke a "Maximum call stack size exceeded" Error
  bookmarks: [Bookmark!]! # Provoke a "Maximum call stack size exceeded" Error
  value: String!
}

There is a loop User => Bookmark => Book => User.

This loop is not a problem as long as Bookmark is a standalone field of User (see User.bookmark).

So this gives me the assumption that reference cycles are properly handled. Afterall GraphQL is designed to achieve graphs of entities (hence the name).

What you were expecting:

It should work fine.

What happened instead:

Once Bookmark is nested, either inside an array (see User.bookmarks), or an object (see User.stuff.bookmark), the introspection that runs in ra-data-graphql fails with

RangeError: Maximum call stack size exceeded
    at Object.validate (index.js:91:12)
    at validate (index.js:177:9)
    at Object.builder (index.js:145:7)
    at buildGqlQuery.ts:132:53
    at Array.reduce (<anonymous>)
    at buildGqlQuery.ts:109:12
    at buildGqlQuery.ts:155:40
    at Array.reduce (<anonymous>)
    at buildGqlQuery.ts:109:12
    at buildGqlQuery.ts:155:40

Related code:

This issue is the same https://github.com/marmelab/react-admin/issues/2938, but it was maybe poorly explained / investigated, and it did not provide any resolution.

Environment

  • React-admin version: 4.8.3
  • Last version that did not exhibit the issue (if applicable):
  • React version: 18.2.0
  • Browser: Chrome
  • Stack trace (in case of a JS error):
RangeError: Maximum call stack size exceeded
   at Object.validate (index.js:91:12)
   at validate (index.js:177:9)
   at Object.builder (index.js:145:7)
   at buildGqlQuery.ts:132:53
   at Array.reduce (<anonymous>)
   at buildGqlQuery.ts:109:12
   at buildGqlQuery.ts:155:40
   at Array.reduce (<anonymous>)
   at buildGqlQuery.ts:109:12
   at buildGqlQuery.ts:155:40

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the introspection failure with the schema in the issue, then read buildGqlQuery.ts around lines 109-155 and the stack trace's validation path. Done means introspection no longer raises "Maximum call stack size exceeded" for the nested object or array fields in the circular User-Bookmark-Book schema.

Written by the indexing model from the issue text.

Assessment

Tech stack
graphql, react, typescript
Domain
api, frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.