From 8f744ebf5a08811995fd057fe78e6d93606c6992 Mon Sep 17 00:00:00 2001 From: Simpy Parveen Date: Tue, 19 Dec 2023 16:31:22 -0500 Subject: [PATCH] Update ComplexityVisitor.js I encountered bug, "RangeError: Maximum call stack size exceeded", that indicates that there's a stack overflow due to excessive recursion. This typically happens when there's an infinite loop or circular reference in the code. This modification ensures that each fragment (in function flattenFragmentSpreads()) is only visited once, preventing infinite recursion. Make sure to test your queries with this modification to see if it resolves the issue. If the problem persists, you may need to inspect your GraphQL queries and schema for any circular references or problematic fragments. --- src/ComplexityVisitor.js | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/ComplexityVisitor.js b/src/ComplexityVisitor.js index 952089b..b9d83f5 100644 --- a/src/ComplexityVisitor.js +++ b/src/ComplexityVisitor.js @@ -98,13 +98,28 @@ export default class ComplexityVisitor { this.SelectionSet = this.flattenFragmentSpreads; } - flattenFragmentSpreads(selectionSet) { - const nextSelections = selectionSet.selections.flatMap((node) => { - if (node.kind === 'FragmentSpread') { - const fragment = this.context.getFragment(node.name.value); + flattenFragmentSpreads(selectionSet, visitedFragments) { + + // Ensure that visitedFragments is a Set or initialize a new Set if not provided + visitedFragments = visitedFragments instanceof Set ? visitedFragments : new Set(); + var nextSelections = selectionSet.selections.flatMap((node) => { + if (node.kind === 'FragmentSpread') { + var fragmentName = node.name.value; + + if (visitedFragments.has(fragmentName)) { + return []; + } + + var fragment = this.context.getFragment(fragmentName); + if (!fragment) return []; - return this.flattenFragmentSpreads(fragment.selectionSet).selections; + var fragment = this.context.getFragment(node.name.value); + + // Add the fragment to the set before the recursive call + visitedFragments.add(fragmentName); + + return this.flattenFragmentSpreads(fragment.selectionSet, visitedFragments).selections; } return node;