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

Toolkit throws TypeError if query returns a non-iterable object #44

Open
odunet opened this issue Nov 5, 2021 · 0 comments
Open

Toolkit throws TypeError if query returns a non-iterable object #44

odunet opened this issue Nov 5, 2021 · 0 comments

Comments

@odunet
Copy link

odunet commented Nov 5, 2021

Problem

Our Gatsby project consumes numerous queries from our single graphql endpoint. The various queries return either an Array, or a non-iterable object. See example below:

// Array datatype
type: [Posts!]!

// non-iterable object
type: LocationSettings!


The toolkit properly handles the queries which return iterable objects (i.e. Array). However, the toolkit fails to properly handle non-iterable objects, by throwing a TypeError. I have an extract of the error stack-trace below:

warn TypeError: partialNodes is not iterable
    at fetchNodeList (/gatsby/node_modules/gatsby-graphql-source-toolkit/src/source-nodes/fetch-nodes/fetch-lists.ts:64:24)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at Object.fetchAllNodes (/gatsby/node_modules/gatsby-graphql-source-toolkit/src/source-nodes/fetch-nodes/fetch-lists.ts:36:24)
    at Object.createNodes (/gatsby/node_modules/gatsby-graphql-source-toolkit/src/source-nodes/node-actions/create-nodes.ts:13:20)
    at async Promise.all (index 0)
    at sourceAllNodes (/gatsby/node_modules/gatsby-graphql-source-toolkit/src/source-nodes/source-all-nodes.ts:20:3)
    at Object.exports.sourceNodes (/gatsby/website/plugins/gatsby-source-odunet/gatsby-node.js:69:5)
    at runAPI (/gatsby/node_modules/gatsby/src/utils/api-runner-node.js:434:16)

Proposed resolution

The stack trace shows that the error is thrown in the code block below. The toolkit expects partialNodes to be iterable. It is therefore unable to handle queries that return non-iterable objects, e.g. type: LocationSettings! above.

for await (const page of paginate(context, plan)) {
const partialNodes = plan.adapter.getItems(page.fieldValue)
for (const node of partialNodes) {
if (!node || node[typeNameField] !== remoteTypeName) {
// Possible when fetching complex interface or union type fields
// or when some node is `null`
continue
}
// TODO: run in parallel?
yield addPaginatedFields(context, nodeDefinition, node)
}
}

A possible fix would introduce a conditional statement to check the partialNodes type, and properly handle it. I have a sample solution below which will replace the block of code above:

 if (Array.isArray(partialNodes)) {
    for (const node of partialNodes) {
      if (!node || node[typeNameField] !== remoteTypeName) {
        // Possible when fetching complex interface or union type fields
        // or when some node is `null`
        continue
      }
      // TODO: run in parallel?
      yield addPaginatedFields(context, nodeDefinition, node)
    }
 } else if (partialNodes && partialNodes[typeNameField] === remoteTypeName) {
     yield addPaginatedFields(context, nodeDefinition, partialNodes)
 }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant