ChilliCream / graphql-platform

Welcome to the home of the Hot Chocolate GraphQL server for .NET, the Strawberry Shake GraphQL client for .NET and Banana Cake Pop the awesome Monaco based GraphQL IDE.
https://chillicream.com
MIT License
5.23k stars 744 forks source link

Error downloading schema when initializing client. dotnet graphql init {url} -> Sequence contains no matching element #5481

Closed jeffward01 closed 1 year ago

jeffward01 commented 2 years ago

Is there an existing issue for this?

Describe the bug

https://github.com/ChilliCream/hotchocolate/issues/4207#issue-991201678

When i initialize a new client, dotnet graphql init https://localhost:9999/graphql -n TestClient -p ProjectName

I have tried various variations of the above command including:

The endpoint has no authentication added.

It downloads the schema then throws Unhandled exception. System.InvalidOperationException: Sequence contains no matching element. I expected it to download the schema and then add the new client to the project

Steps to reproduce

Note: This is a private GraphQL endpoint that unfortunately I cannot share the endpoint URL - I would love some direction on debugging this myself.

If there is a way to send a private message, I might be able to share the Endpoint, it just cannot be broadcasted publically

  1. Add the Strawberry Shake CLI tools
  2. Install the required packages
  3. Add a GraphQL client to your project using the CLI tools with the command dotnet graphql init https://localhost:9999/graphql -n TestClient

Relevant log output

Download schema started.
Download schema completed in 884 ms
Unhandled exception. System.InvalidOperationException: Sequence contains no matching element
   at System.Linq.ThrowHelper.ThrowNoMatchException()
   at System.Linq.Enumerable.First[TSource](IEnumerable`1 source, Func`2 predicate)
   at HotChocolate.Utilities.Introspection.SchemaFeatures.FromIntrospectionResult(IntrospectionResult result) in /home/vsts/work/1/s/src/HotChocolate/Utilities/src/Utilities.Introspection/SchemaFeatures.cs:line 27
   at HotChocolate.Utilities.Introspection.IntrospectionClient.GetSchemaFeaturesAsync(HttpClient client, CancellationToken cancellationToken) in /home/vsts/work/1/s/src/HotChocolate/Utilities/src/Utilities.Introspection/IntrospectionClient.cs:line 97
   at HotChocolate.Utilities.Introspection.IntrospectionClient.DownloadSchemaAsync(HttpClient client, CancellationToken cancellationToken) in /home/vsts/work/1/s/src/HotChocolate/Utilities/src/Utilities.Introspection/IntrospectionClient.cs:line 67
   at HotChocolate.Utilities.Introspection.IntrospectionClient.DownloadSchemaAsync(HttpClient client, Stream stream, CancellationToken cancellationToken) in /home/vsts/work/1/s/src/HotChocolate/Utilities/src/Utilities.Introspection/IntrospectionClient.cs:line 49
   at StrawberryShake.Tools.DefaultFileSystem.WriteToAsync(String fileName, Func`2 write) in /home/vsts/work/1/s/src/StrawberryShake/Tooling/src/dotnet-graphql/DefaultFileSystem.cs:line 81
   at StrawberryShake.Tools.IntrospectionHelper.DownloadSchemaAsync(HttpClient client, IFileSystem fileSystem, IActivity activity, String fileName, CancellationToken cancellationToken) in /home/vsts/work/1/s/src/StrawberryShake/Tooling/src/dotnet-graphql/IntrospectionHelper.cs:line 21
   at StrawberryShake.Tools.InitCommandHandler.DownloadSchemaAsync(InitCommandContext context, CancellationToken cancellationToken) in /home/vsts/work/1/s/src/StrawberryShake/Tooling/src/dotnet-graphql/InitCommandHandler.cs:line 92
   at StrawberryShake.Tools.InitCommandHandler.ExecuteInternalAsync(InitCommandContext context, CancellationToken cancellationToken) in /home/vsts/work/1/s/src/StrawberryShake/Tooling/src/dotnet-graphql/InitCommandHandler.cs:line 64
   at StrawberryShake.Tools.InitCommandHandler.ExecuteAsync(InitCommandArguments arguments, CancellationToken cancellationToken) in /home/vsts/work/1/s/src/StrawberryShake/Tooling/src/dotnet-graphql/InitCommandHandler.cs:line 50
   at McMaster.Extensions.CommandLineUtils.CommandLineApplication.ExecuteAsync(String[] args, CancellationToken cancellationToken)
   at StrawberryShake.Tools.Program.<Main>(String[] args)

Additional Context?

I have access to:

I'm not sure why this error is occurring, it seems that it was originally reported by another user here: https://github.com/ChilliCream/hotchocolate/issues/4207

If someone can point me in the right direction for debugging, or help assist me with bug discovery, that would be much appreciated.

I'd much rather use a tool like Strawberry Shake to generate a client rather than manually build all the classes for the client myself.

BIG thanks for such an amazing tool!

Product

Strawberry Shake

Version

12.15.0

fleed commented 2 years ago

I'm experiencing the same issue

tobias-tengler commented 2 years ago

Edit: I misread your issue. Ignore my comment below...

The initialization works by doing an introspection query to the server endpoint. Does your server allow introspection queries? Does your server mandate the presence of an access token or another form of identification?

Can you issue a regular introspection query through cURL for example?

curl 'http://your-schema-endpoint.com' -X POST -H 'content-type: application/json' --data-raw '{"query":"{\n  __schema {\n    queryType {\n      name\n    }\n  }\n}"}'

If this also doesn't work then the issue lies with the configuration of your server or the cURL request (and by extensions Strawberry Shake) is missing some form of identification, e.g. an Authorize header for example. Which could be added by adding a -X argument to the Strawberry Shake initialization process: https://chillicream.com/docs/strawberryshake/v12/tooling#initialize-project

jeffward01 commented 2 years ago

Hello! Thank you for the quick reply @tobias-tengler

Introspection Query ran with success

This is the Introspection Command which I run with success:

Strawberry Shake Commands ran with error

I then try and run these commands using StrawberryShake:

(I also use the -p flag)

Error from the Strawberry Shake init command:

And all of these commands result in the same error message of below:

$ dotnet graphql init "http://localhost:9999/graphql" -x "Content-Type:application/json" -n MyClient

Download schema started.
Download schema completed in 118 ms
Unhandled exception. System.InvalidOperationException: Sequence contains no matching element
   at System.Linq.ThrowHelper.ThrowNoMatchException()
   at System.Linq.Enumerable.First[TSource](IEnumerable`1 source, Func`2 predicate)
   at HotChocolate.Utilities.Introspection.SchemaFeatures.FromIntrospectionResult(IntrospectionResult result) in /home/vsts/work/1/s/src/HotChocolate/Utilities/src/Utilities.Introspection/SchemaFeatures.cs:line 27
   at HotChocolate.Utilities.Introspection.IntrospectionClient.GetSchemaFeaturesAsync(HttpClient client, CancellationToken cancellationToken) in /home/vsts/work/1/s/src/HotChocolate/Utilities/src/Utilities.Introspection/IntrospectionClient.cs:line 97
   at HotChocolate.Utilities.Introspection.IntrospectionClient.DownloadSchemaAsync(HttpClient client, CancellationToken cancellationToken) in /home/vsts/work/1/s/src/HotChocolate/Utilities/src/Utilities.Introspection/IntrospectionClient.cs:line 67
   at HotChocolate.Utilities.Introspection.IntrospectionClient.DownloadSchemaAsync(HttpClient client, Stream stream, CancellationToken cancellationToken) in /home/vsts/work/1/s/src/HotChocolate/Utilities/src/Utilities.Introspection/IntrospectionClient.cs:line 49
   at StrawberryShake.Tools.DefaultFileSystem.WriteToAsync(String fileName, Func`2 write) in /home/vsts/work/1/s/src/StrawberryShake/Tooling/src/dotnet-graphql/DefaultFileSystem.cs:line 81
   at StrawberryShake.Tools.IntrospectionHelper.DownloadSchemaAsync(HttpClient client, IFileSystem fileSystem, IActivity activity, String fileName, CancellationToken cancellationToken) in /home/vsts/work/1/s/src/StrawberryShake/Tooling/src/dotnet-graphql/IntrospectionHelper.cs:line 21
   at StrawberryShake.Tools.InitCommandHandler.DownloadSchemaAsync(InitCommandContext context, CancellationToken cancellationToken) in /home/vsts/work/1/s/src/StrawberryShake/Tooling/src/dotnet-graphql/InitCommandHandler.cs:line 92
   at StrawberryShake.Tools.InitCommandHandler.ExecuteInternalAsync(InitCommandContext context, CancellationToken cancellationToken) in /home/vsts/work/1/s/src/StrawberryShake/Tooling/src/dotnet-graphql/InitCommandHandler.cs:line 64
   at StrawberryShake.Tools.InitCommandHandler.ExecuteAsync(InitCommandArguments arguments, CancellationToken cancellationToken) in /home/vsts/work/1/s/src/StrawberryShake/Tooling/src/dotnet-graphql/InitCommandHandler.cs:line 50
   at McMaster.Extensions.CommandLineUtils.CommandLineApplication.ExecuteAsync(String[] args, CancellationToken cancellationToken)
   at StrawberryShake.Tools.Program.<Main>(String[] args)

Screenshot of Curl Introspection query result:

Attached is an example of the JSON that is generated from the result of the introspection query (sorry its a screenshot of some of the JSON data that is expanded)

Online JSON Viewer


Please let me know what else I can do to assist in the debugging.

Thanks!

tobias-tengler commented 2 years ago

Thanks for the detailed answer. As I already mentioned in my edit to my original comment, the issue doesn't seem to lie in the acquisition of the schema - I misread your issue. I think what would help is

fleed commented 2 years ago

Hello

I add my data, hopefully it helps identifying the issue:

The introspection request body:

{
  __schema {
    types {
      name
    }
  }
}

The answer:

{
    "data": {
        "__schema": {
            "types": [
                {
                    "name": "BigDecimal"
                },
                {
                    "name": "BigInt"
                },
                {
                    "name": "BlockChangedFilter"
                },
                {
                    "name": "Block_height"
                },
                {
                    "name": "Boolean"
                },
                {
                    "name": "Bytes"
                },
                {
                    "name": "Float"
                },
                {
                    "name": "ID"
                },
                {
                    "name": "Int"
                },
                {
                    "name": "MarketType"
                },
                {
                    "name": "OrderDirection"
                },
                {
                    "name": "Query"
                },
                {
                    "name": "String"
                },
                {
                    "name": "Subscription"
                },
                {
                    "name": "Token"
                },
                {
                    "name": "TokenPhase"
                },
                {
                    "name": "Token_filter"
                },
                {
                    "name": "Token_orderBy"
                },
                {
                    "name": "Transaction"
                },
                {
                    "name": "Transaction_filter"
                },
                {
                    "name": "Transaction_orderBy"
                },
                {
                    "name": "_Block_"
                },
                {
                    "name": "_Meta_"
                },
                {
                    "name": "_SubgraphErrorPolicy_"
                }
            ]
        }
    }
}

I tried it with the version 13.0.0-preview.70 of the tool and it returns the same error. I also tried some older versions from 12.4.0 on and they all throw the same exception.

I tried to get the SDL with Banana Cake Pop, but the request returned an error

CleanShot 2022-10-15 at 08 42 08@2x

michaelstaib commented 2 years ago

This is interesting... it seems the internal __Directive type is missing... there should be at least one in a spec compliant GraphQL schema. Can you send us a dump of the introspection? If you do not want it in the issue send it to me as a DM on slack. slack.chillicream.com

In any case we should be more defensive since the code that fails tries to determine what spec features a GraphQL server implements. So, in this case we could set everything to a legacy schema.

Still, I would like to have an introspection dump to verify.

michaelstaib commented 2 years ago

So verified this now in the code ... concrete the type __Directive is missing in your schema which is the an object type to represent directives in your schema like @skip or @include. The __Directive type must exist in order to have a spec valid schema.

But, in any case, our error is not nice. Still not sure if we should just let it through or not. I mean if there are more spec violations in the schema it could very well just throw somewhere else.

We could inform that there is an issue with the schema and that a certain type is missing. I will discuss that with the team.

Still, if you can, send us the dump so that we can see if there are more issues in it.

michaelstaib commented 2 years ago

@fleed you schema to be valid should contain the following introspection types as well as your internal types. This is a screenshot from the GitHub GraphQL api for instance.

image

Here is for instance the spec section where the __Directive type is referred to: https://spec.graphql.org/June2018/#sec-The-__Directive-Type

michaelstaib commented 2 years ago

Which GraphQL server are you guys using?

tobias-tengler commented 2 years ago

I already talked with the original reporter @jeffward01 about this in DM yesterday and we came to the same conclusion that the GraphQL server they're using isn't fully spec compliant. They are using https://github.com/99designs/gqlgen. I don't know about @fleed.

I also already suggested a workaround by just doing the initial initialization of the client against a different schema and then swapping the schema.graphql file for the one they can download through BCP. I'm still waiting on feedback though. I also have access to @jeffward01 GraphQL schema, if you need it, just DM me on Slack.

fleed commented 2 years ago

In my case, a service hosted on thegraph.com

michaelstaib commented 1 year ago

This one is fixed with V13.

michaelstaib commented 1 year ago

We are now a bit more defensive in determining what spec features are allowed. So we accept GraphQL server that might not be 100% spec compliant.