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

[2.6.7] TypeError: Cannot read property 'some' of undefined #2961

Closed
goto1 opened this issue Jul 1, 2019 · 17 comments
Closed

[2.6.7] TypeError: Cannot read property 'some' of undefined #2961

goto1 opened this issue Jul 1, 2019 · 17 comments

Comments

@goto1
Copy link

goto1 commented Jul 1, 2019

Hello!

First of all, thank you all for this great tool.

I've noticed this morning an error message when updating to v2.6.7.

package.json

{
    "apollo-server": "^2.6.7",
    "apollo-server-express": "^2.6.7",
    "graphql": "^14.4.1"
}

package.json where the issue does not occur:

{
    "apollo-server": "^2.6.4",
    "apollo-server-express": "^2.6.4",
    "graphql": "^14.3.1"
}

Actual behavior

/Users/tom/Development/backend/node_modules/apollo-server-core/dist/utils/isDirectiveDefined.js:11
        return typeDef.definitions.some(definition => definition.kind === language_1.Kind.DIRECTIVE_DEFINITION &&
                                   ^

TypeError: Cannot read property 'some' of undefined
    at typeDefs.some.typeDef (/Users/tom/Development/backend/node_modules/apollo-server-core/dist/utils/isDirectiveDefined.js:11:36)
    at Array.some (<anonymous>)
    at Object.exports.isDirectiveDefined (/Users/tom/Development/backend/node_modules/apollo-server-core/dist/utils/isDirectiveDefined.js:7:21)
    at new ApolloServerBase (/Users/tom/Development/backend/node_modules/apollo-server-core/dist/ApolloServer.js:146:39)
    at new ApolloServer (/Users/tom/Development/backend/node_modules/apollo-server-express/dist/ApolloServer.js:46:9)
    at Object.<anonymous> (/Users/tom/Development/backend/app/app.js:31:16)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Module.require (module.js:597:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/Users/tom/Development/backend/index.js:6:13)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Function.Module.runMain (module.js:694:10)
    at startup (bootstrap_node.js:204:16)
    at bootstrap_node.js:625:3

Environment

  • node v8.16.0
  • macOS 10.14.5

One thing I noticed is that when I updated both apollo-server and apollo-server-express to v2.6.7 but left the graphql package at v14.3.1 the issue is still there.

Please let me know if there's any additional info needed that I could provide.

Thank you!

@abernix
Copy link
Member

abernix commented Jul 1, 2019

Are you sure you've run npm install with those versions? The fix for this was the entire reason for v2.6.7. #2924

@abernix
Copy link
Member

abernix commented Jul 1, 2019

Since the error is happening in apollo-server-core, can you run npm ls apollo-server-core and provide that output here?

@goto1
Copy link
Author

goto1 commented Jul 1, 2019

Just checked now.

Here's the package.json that works:

{
    "apollo-server": "^2.6.4",
    "apollo-server-express": "^2.6.4",
    "graphql": "^14.4.1"
}

Here's the package.json that causes issues:

{
    "apollo-server": "^2.6.7",
    "apollo-server-express": "^2.6.7",
    "graphql": "^14.4.1"
}

Output:

st/utils/isDirectiveDefined.js:11
        return typeDef.definitions.some(definition => definition.kind === language_1.Kind.DIRECTIVE_DEFINITION &&
                                   ^

TypeError: Cannot read property 'some' of undefined

npm ls apollo-server-core

backend $ npm ls apollo-server-core
project@0.1.10 /Users/tom/Development/backend
├─┬ apollo-server@2.6.7
│ └─┬ apollo-server-core@2.6.7
│   └─┬ apollo-engine-reporting@1.3.5
│     └── apollo-server-core@2.6.7  deduped
└─┬ apollo-server-express@2.6.7
  └── apollo-server-core@2.6.7  deduped

Let me know if you have any other questions.

Thanks!


EDIT:
Just in case I ran rm -rf node_modules and npm install again with v2.6.7 and issue still persists.

@abernix
Copy link
Member

abernix commented Jul 1, 2019

@goto1 How are you setting your typeDefs on the ApolloServer constructor? Strings? DocumentNodes (i.e. gql tags)?

@goto1
Copy link
Author

goto1 commented Jul 1, 2019

The setup looks like this:

const { gql } = require('apollo-server-express')

// Book.js
const Book = gql`
  type Book {...}
`
module.exports = () => [Book]

// Author.js
const Author = gql`
  type Author {...}
`
module.exports = () => [Author]

// index.js
const Author = require('./Author')
const Book = require('./Book')

const root = gql`...`
const typeDefs = [root, Author, Book]
const apollo = new ApolloServer({
  typeDefs,
  ...
})

Let me know if you have any other questions.

Thanks!

@abernix
Copy link
Member

abernix commented Jul 1, 2019

To be honest, I'd like to figure out more concretely where our internal typings have led us awry on getting this right so a runnable reproduction would be super helpful.

I'm curious what it is about the format of your typeDefs which is failing in this logic:

export const isDirectiveDefined = (
typeDefs: (DocumentNode | string)[],
directiveName: string,
): boolean => {
// If we didn't receive an array of what we want, ensure it's an array.
typeDefs = Array.isArray(typeDefs) ? typeDefs : [typeDefs];
return typeDefs.some(typeDef => {
if (typeof typeDef === 'string') {
typeDef = gql(typeDef);
}
return typeDef.definitions.some(
definition =>
definition.kind === Kind.DIRECTIVE_DEFINITION &&
definition.name.value === directiveName,
);
});
};

@goto1
Copy link
Author

goto1 commented Jul 1, 2019

Ok no problem. I will work on an example that I can share when I get home from work. One thing that might be of your interest, however, if you look at the code snippet I provided above, essentially what I am doing is the following:

const root = gql`...`
const type1 = () => [gql`...`]
const type2 = () => [gql`...`]

// then
const typeDefs = [root, type1, type2]; // [DocumentNode, function, function]

So when it goes through the items in the typeDef array, it seems to be only handling a string and an array, but in my case the return type is a function:

return typeDefs.some(typeDef => {
  console.log("typeof typeDef", typeof typeDef);
  console.log('typeDef', typeDef);

  if (typeof typeDef === 'string') {
      typeDef = gql(typeDef);
  }

  return typeDef.definitions.some(
      definition =>
      definition.kind === Kind.DIRECTIVE_DEFINITION &&
      definition.name.value === directiveName,
  );
});

Which is why it fails when a function gets passed:

typeof typeDef object
typeDef { kind: 'Document', ...}

typeof typeDef function # fails here
typeDef function () {
  return [Author];
}

/Users/tom/Development/att/murray-run/backend/node_modules/apollo-server-core/dist/utils/isDirectiveDefined.js:12
    return typeDef.definitions.some(
                               ^

TypeError: Cannot read property 'some' of undefined

This seems to work in v2.6.4 though (my current setup, that is).

Not sure if this is the intended use and/or behavior, however, but one fix that comes to my mind would simply to unpack the array that's passed (like in my case):

if (typeof typeDef === 'string') {
  typeDef = gql(typeDef);
}

const temp = typeof typeDef === 'function' ? typeDef() : typeDef
// In a case where it's an array
// 
// [ { kind: 'Document',
// definitions: [ [Object], [Object] ],
// loc: { start: 0, end: 241 } } ]
//

if (Array.isArray(temp)) {
  temp.forEach(item => {
    // item.definitions.some()
  })
}

if (temp.kind === 'Document') {
  // item.definitions.some()
}

This is just a quick solution that comes to my mind, but this can be handled a little better for sure.

@abernix
Copy link
Member

abernix commented Jul 1, 2019

Thanks for boiling it down. I'd love to know where you picked up that pattern of passing typeDefs as a function. I'm somewhat surprised that works but I'm very curious what you're gaining out of it and why you wouldn't be able to just pass the result of invoking the function?

@abernix
Copy link
Member

abernix commented Jul 1, 2019

I guess this is a historical artifact back from graphql-tools: Which allowed this pattern!

https://github.com/apollographql/graphql-tools/blob/e54921b76b0ac22e55b3b8018a23e874711c72a2/src/Interfaces.ts#L87-L88

I'm really curious what your use-case is here because, to be honest, I'd really rather those be statically analyzable.

@goto1
Copy link
Author

goto1 commented Jul 1, 2019

Not sure if this is still the case, but there was a need to do something like the following when storing typeDef in multiple files:

// Book.js
const Book = gql`...`

// Author.js
const Book = require('./Book.js')
const Author = gql`
  type Author {
    firstName: String!
    lastName: String!
    books: [Book]!
}`
module.exports = () => [Author, Book]
`

Otherwise in Author.js it'd complain that the Book type was not specified, or whatever.

I will try just to simply do the following, without actually exporting types that my other type relies on, and then just combine them at the end with typeDefs:

const Author  = gql`...`
module.exports = Author;

@abernix
Copy link
Member

abernix commented Jul 1, 2019

As another consideration, you might also try modules, which is only documented in this PR at the moment: https://github.com/apollographql/apollo-server/pull/2576/files#diff-2d27a587f5c91caac3eaf399fc6c3a83

@goto1
Copy link
Author

goto1 commented Jul 1, 2019

Great, thanks a lot. I think this can be closed now.

Thanks a lot for your help and contributions to this project!

@abernix
Copy link
Member

abernix commented Jul 1, 2019

You're welcome! And thank you for reporting this and your prompt and thorough/detailed responses.

I'll close it, but if it continues to be a pain-point, we'll consider what bringing this functionality back might look like, but I'd lean heavily on the rather not button for now for reasons I can go into if it continues to be a recurring problem. 😁

@abernix abernix closed this as completed Jul 1, 2019
@goto1
Copy link
Author

goto1 commented Aug 4, 2019

In my situation, where I had a setup similar to the following:

// Author.js
const Book = require('./Book.js')
const Author = gql`
  type Author {
    books: [Book]
  }
`
module.exports = () => [Author, Book]

// Book.js
const Book = gql`
  type Book { ... }
`
module.exports = Book

when you're passing your typeDefs to the ApolloServer constructor, you could just simply combine them like such:

const isFunction = require('lodash/isFunction')

function combineTypeDefs(items) {
  return items.reduce((combinedTypeDefs, item) => {
    const typeDefs = isFunction(item) ? item() : item

    return Array.isArray(typeDefs)
      ? [...combinedTypeDefs, ...typeDefs]
      : [...combinedTypeDefs, typeDefs]
  }, [])

const typeDefs = combineTypeDefs([
    Author,   // () => [Author, Book]
    Book
])

Of course, this might not cover all your cases so you'll have to take care of them, but this would've been my solution if I didn't have the ability to just simply switching to

const Author = gql`...`

module.exports = Author

@xianbinKit
Copy link

Same for me. It works on 2.6.1, but doesn't work on 2.9.7

@xeroxoid
Copy link

Excellent issue and great research.

We also used the () => [Book] type exports and this caused issues for any version after 2.6.4

The correct solution IMO is to avoid this syntax for exporting types and just export types as DocumentNode or [DocumentNode, DocumentNode] and flatten them before passing them to typeDefs.

@waleedarshad-vf
Copy link

waleedarshad-vf commented Jul 17, 2020

Facing same issue TypeError: Cannot read property 'some' of undefined
Using v6 graphql-tools

"@graphql-tools/mock": "^6.0.14",
"@graphql-tools/schema": "^6.0.14",
"@graphql-tools/stitch": "^6.0.14",
"apollo-server": "^2.15.1",
"apollo-server-express": "^2.15.1",
[1594973287355] ERROR (21092 on macbookpros-MacBook-Pro.local): Caught exception: TypeError: Cannot read property 'some' of undefined
    err: {
      "type": "TypeError",
      "message": "Cannot read property 'some' of undefined",
      "stack":
          TypeError: Cannot read property 'some' of undefined
              at typeDefs.some.typeDef (/Users/macbookpro/Documents/eFuse_BE/node_modules/apollo-server-core/dist/utils/isDirectiveDefined.js:12:36)
              at Array.some (<anonymous>)
              at Object.exports.isDirectiveDefined (/Users/macbookpro/Documents/eFuse_BE/node_modules/apollo-server-core/dist/utils/isDirectiveDefined.js:8:21)
              at ApolloServer.initSchema (/Users/macbookpro/Documents/eFuse_BE/node_modules/apollo-server-core/dist/ApolloServer.js:243:39)
              at new ApolloServerBase (/Users/macbookpro/Documents/eFuse_BE/node_modules/apollo-server-core/dist/ApolloServer.js:194:30)
              at new ApolloServer (/Users/macbookpro/Documents/eFuse_BE/node_modules/apollo-server-express/dist/ApolloServer.js:60:9)
              at new ApolloServer (/Users/macbookpro/Documents/eFuse_BE/node_modules/apollo-server/dist/index.js:32:9)
              at Object.<anonymous> (/Users/macbookpro/Documents/eFuse_BE/graphql/index.js:12:16)
              at Module._compile (internal/modules/cjs/loader.js:778:30)
              at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
              at Module.load (internal/modules/cjs/loader.js:653:32)
              at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
              at Function.Module._load (internal/modules/cjs/loader.js:585:3)
              at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
              at startup (internal/bootstrap/node.js:283:19)
              at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)
    }
TypeError: Cannot read property 'some' of undefined
    at typeDefs.some.typeDef (/Users/macbookpro/Documents/eFuse_BE/node_modules/apollo-server-core/dist/utils/isDirectiveDefined.js:12:36)
    at Array.some (<anonymous>)
    at Object.exports.isDirectiveDefined (/Users/macbookpro/Documents/eFuse_BE/node_modules/apollo-server-core/dist/utils/isDirectiveDefined.js:8:21)
    at ApolloServer.initSchema (/Users/macbookpro/Documents/eFuse_BE/node_modules/apollo-server-core/dist/ApolloServer.js:243:39)
    at new ApolloServerBase (/Users/macbookpro/Documents/eFuse_BE/node_modules/apollo-server-core/dist/ApolloServer.js:194:30)
    at new ApolloServer (/Users/macbookpro/Documents/eFuse_BE/node_modules/apollo-server-express/dist/ApolloServer.js:60:9)
    at new ApolloServer (/Users/macbookpro/Documents/eFuse_BE/node_modules/apollo-server/dist/index.js:32:9)
    at Object.<anonymous> (/Users/macbookpro/Documents/eFuse_BE/graphql/index.js:12:16)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
    at startup (internal/bootstrap/node.js:283:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)
(node:21092) ExperimentalWarning: The fs.promises API is experimental
[nodemon] app crashed - waiting for file changes before starting...

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

No branches or pull requests

5 participants