question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

urql-introspection plugin query does not match the urql devtools query causing error

See original GitHub issue

Describe the bug The introspection query that the urql-introspection plugin uses to generate the schema does not match the one that urql’s devtoolsExchange uses. Specifically, it is missing __typename in several places.

This would be fine, however when urql’s cacheExchange (@urql/exchange-graphcache) uses this generated schema, an uncaught error occurs when the devtoolsExchange (@urql/devtools) attempts to request its own introspection query.

The problem is that the devtoolsExchange’s query includes some fields that aren’t known to cacheExchange due to the differences in the introspection query.

To Reproduce Steps to reproduce the behavior:

  1. use graphql-codegen with the urql-inspection plugin to generate a schema
  2. import the schema into urql cacheExchange
  3. add the devtoolsExchange in urql client
  4. load the app in a browser
  5. Result: app will load, then once the urql devtools requests its own introspection query, cacheExchange will throw an error when checking the response.
  1. My GraphQL schema:

Is quite large and not the issue here.

  1. My GraphQL operations:
########################################
# graphql-codegen introspection query:
########################################
query IntrospectionQuery {
  __schema {
    queryType {
      name
    }
    mutationType {
      name
    }
    subscriptionType {
      name
    }
    types {
      ...FullType
    }
    directives {
      name
      description
      locations
      args {
        ...InputValue
      }
    }
  }
}

fragment FullType on __Type {
  kind
  name
  description
  fields(includeDeprecated: true) {
    name
    description
    args {
      ...InputValue
    }
    type {
      ...TypeRef
    }
    isDeprecated
    deprecationReason
  }
  inputFields {
    ...InputValue
  }
  interfaces {
    ...TypeRef
  }
  enumValues(includeDeprecated: true) {
    name
    description
    isDeprecated
    deprecationReason
  }
  possibleTypes {
    ...TypeRef
  }
}

fragment InputValue on __InputValue {
  name
  description
  type {
    ...TypeRef
  }
  defaultValue
}

fragment TypeRef on __Type {
  kind
  name
  ofType {
    kind
    name
    ofType {
      kind
      name
      ofType {
        kind
        name
        ofType {
          kind
          name
          ofType {
            kind
            name
            ofType {
              kind
              name
              ofType {
                kind
                name
              }
            }
          }
        }
      }
    }
  }
}

########################################
# urql-devtools introspection query:
########################################
query IntrospectionQuery {
  __schema {
    queryType {
      name
      __typename
    }
    mutationType {
      name
      __typename
    }
    subscriptionType {
      name
      __typename
    }
    types {
      ...FullType
      __typename
    }
    directives {
      name
      description
      locations
      args {
        ...InputValue
        __typename
      }
      __typename
    }
    __typename
  }
}

fragment FullType on __Type {
  kind
  name
  description
  fields(includeDeprecated: true) {
    name
    description
    args {
      ...InputValue
      __typename
    }
    type {
      ...TypeRef
      __typename
    }
    isDeprecated
    deprecationReason
    __typename
  }
  inputFields {
    ...InputValue
    __typename
  }
  interfaces {
    ...TypeRef
    __typename
  }
  enumValues(includeDeprecated: true) {
    name
    description
    isDeprecated
    deprecationReason
    __typename
  }
  possibleTypes {
    ...TypeRef
    __typename
  }
}

fragment InputValue on __InputValue {
  name
  description
  type {
    ...TypeRef
    __typename
  }
  defaultValue
}

fragment TypeRef on __Type {
  kind
  name
  ofType {
    kind
    name
    ofType {
      kind
      name
      ofType {
        kind
        name
        ofType {
          kind
          name
          ofType {
            kind
            name
            ofType {
              kind
              name
              ofType {
                kind
                name
                __typename
              }
              __typename
            }
            __typename
          }
          __typename
        }
        __typename
      }
      __typename
    }
    __typename
  }
}

Here is the diff between the two queries:

5d4
<       __typename
9d7
<       __typename
13d10
<       __typename
17d13
<       __typename
25d20
<         __typename
27d21
<       __typename
29d22
<     __typename
42d34
<       __typename
46d37
<       __typename
50d40
<     __typename
54d43
<     __typename
58d46
<     __typename
65d52
<     __typename
69d55
<     __typename
78d63
<     __typename
107d91
<                 __typename
109d92
<               __typename
111d93
<             __typename
113d94
<           __typename
115d95
<         __typename
117d96
<       __typename
119d97
<     __typename
  1. My codegen.yml config file:
overwrite: true
schema: 'http://localhost:4000/graphql'
generates:
  src/graphql/schema.ts:
    plugins:
      - 'urql-introspection'
    config:
      useTypeImports: true
      includeEnums: true
      includeInputs: true
      includeDirectives: true
      includeScalars: true

Expected behavior

Ideally the two schemas should match or at least not conflict so much that it causes page-breaking errors.

One possibility could be adding an includeTypenames: boolean option to the urql-introspection plugin to adjust the query.

Environment:

  • OS: macOS 11.3
  • @graphql-codegen/cli: 1.21.4
  • @graphql-codegen/urql-introspection: 1.2.0
  • NodeJS: v14.16.0

Additional context Apologies but I don’t see how I could put this into a codesandbox in any meaningful way. For reference here is how the client is instantiated in my application:

import { createClient, dedupExchange, fetchExchange } from 'urql';
import { cacheExchange } from '@urql/exchange-graphcache';
import { devtoolsExchange } from '@urql/devtools';
import schema from '@src/graphql/schema';

const client = createClient({
  url: 'http://localhost:4000/graphql',
  requestPolicy: 'cache-first',
  exchanges: [
    devtoolsExchange,
    dedupExchange,
    cacheExchange({ schema }),
    fetchExchange,
  ],
});

The specific error is the following:

Unhandled Rejection (Graphcache Error): Invalid Object type: The type `__Schema` is not an object in the defined schema, but the GraphQL document is traversing it.
(Caused At: "IntrospectionQuery" query)
https://bit.ly/2XbVrpR#3

This error originates here: https://github.com/FormidableLabs/urql/blob/4c1a9d9bd3df55207aeff1ffc3e2b3262f27cbc9/exchanges/graphcache/src/ast/schemaPredicates.ts#L70

Removing the devtoolsExchange from the client removes the error, but at the expense of having no devtools 😢

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
kittencommented, May 12, 2021

@disbelief Awesome! No worries though, I merely mean that more details around errors without speculation often helps us to resolve an issue quicker 🙌 Then again, since we have time to address these issues during normal work hours we often are able to fix them on the same day either way

1reaction
disbeliefcommented, May 12, 2021

I can confirm that upgrading to @urql/exchange-graphcache@4.1.1 has resolved the issue for my installation. Will leave the ticket open in case you have a specific policy around confirming/labelling/closing issues.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Errors | urql Documentation
When you're passing an introspected schema to the cache exchange, it is able to check whether all your queries are valid. This error...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found