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

Generating client produces "Undefined type String" error #200

Closed
Waitak opened this issue May 27, 2022 · 1 comment
Closed

Generating client produces "Undefined type String" error #200

Waitak opened this issue May 27, 2022 · 1 comment
Labels
bug Something isn't working

Comments

@Waitak
Copy link

Waitak commented May 27, 2022

Describe the bug
Running genqlient --init with this genqlient.graphql and this schema.graphql loaded from the Spire Maritime API using

% get-graphql-schema https://api.spire.com/graphql --sdl > api/schema.graphql

generates this error:

schema.graphql:107: invalid schema: Undefined type String.
exit status 1

To Reproduce

% go run github.com/Khan/genqlient --init

Expected behavior

I expected generated.go to be created.

genqlient version
v0.4.0

Additional context
Add any other context about the problem here.

@Waitak Waitak added the bug Something isn't working label May 27, 2022
@benjaminjkraft
Copy link
Collaborator

Thanks for the report! The incorrect error is due to #175; in this case a better error is

/home/benkraft/src/genqlient/tmp/schema.graphql:4: invalid schema: Cannot redeclare directive specifiedBy.

The issue seems to be that get-graphql-schema filters out most of the builtin GraphQL types and directives (so the schema isn't valid without including the "prelude" that defines String, etc.) but not @specifiedBy (which is also builtin, thus now defined twice). Ideally gqlparser would be a little more flexible in this case (the spec says built-in directives "may" be omitted but built-in types "must" be); I'll file an issue there. But in the meantime, the easiest thing for you is probably to simply remove that definition, and/or ask the get-graphql-schema folks to filter it out.

@benjaminjkraft benjaminjkraft closed this as not planned Won't fix, can't repro, duplicate, stale May 27, 2022
benjaminjkraft added a commit that referenced this issue Jun 6, 2022
GraphQL schemas have some builtin types, like `String`. The spec says
your SDL must not include those, but in practice some schemas do. (This
is probably because introspection must include them, and some tools that
create SDL from introspection don't know they're supposed to filter them
out.) Anyway, we've since #145 had logic to handle this; we just parse
with and without the prelude that defines them and see which works.

The problem is that this makes for very confusing error messages if you
have an invalid schema. (Or if you have a schema that you think is valid
but gqlparser doesn't, which is the more common case in the wild; see
for example #200.) Right now if both ways error we take the
without-prelude error, which if you didn't define the builtins is just
`undefined type String`; if we took the with-prelude error then if you
did define the builtins you'd just get `type String defined twice`. So
we actually have to be smart if we want good error messages for
everyone.

So in this commit we are smart: we check if your schema defines
`String`, and include the prelude only if it does not. To do this I
basically inlined `gqlparser.LoadSchema` (twice), so that in between
parsing and validation we can check if you have `String` and if not add
the prelude. This should in theory be both more efficient
(we don't have to do everything twice) and give better error messages,
although it's a bit more code.

Test plan: make check
benjaminjkraft added a commit that referenced this issue Jun 6, 2022
GraphQL schemas have some builtin types, like `String`. The spec says
your SDL must not include those, but in practice some schemas do. (This
is probably because introspection must include them, and some tools that
create SDL from introspection don't know they're supposed to filter them
out.) Anyway, we've since #145 had logic to handle this; we just parse
with and without the prelude that defines them and see which works.

The problem is that this makes for very confusing error messages if you
have an invalid schema. (Or if you have a schema that you think is valid
but gqlparser doesn't, which is the more common case in the wild; see
for example #200.) Right now if both ways error we take the
without-prelude error, which if you didn't define the builtins is just
`undefined type String`; if we took the with-prelude error then if you
did define the builtins you'd just get `type String defined twice`. So
we actually have to be smart if we want good error messages for
everyone.

So in this commit we are smart: we check if your schema defines
`String`, and include the prelude only if it does not. To do this I
basically inlined `gqlparser.LoadSchema` (twice), so that in between
parsing and validation we can check if you have `String` and if not add
the prelude. This should in theory be both more efficient (we don't
have to do everything twice) and give better error messages,
although it's a bit more code.

Fixes #175.

Test plan: make check
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants