ChilliCream/graphql-platform

Subscription-level directive with argument results in internal server error

fabianoliver opened this issue · 1 comments

Product

Nitro

Version

14.1.0

Link to minimal reproduction

https://github.com/fabianoliver/hotchocolate-bug-2024-08-11/tree/main

Steps to reproduce

Run the server & run the following query in Nitro:

subscription test @bug(test: 123) {
  bookAdded {
    title
  }
}

What is expected?

A valid result

What is actually happening?

Returns an internal server error:

{
"message": "",
"name": "ServerError",
"statusCode": 500,
"statusText": "Internal Server Error",
"bodyText": ""
}

Relevant log output

l: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.InvalidOperationException: Invalid accept media types specified.
at HotChocolate.AspNetCore.Serialization.DefaultHttpResponseFormatter.FormatAsync(HttpResponse response, IExecutionResult result, AcceptMediaType[] acceptMediaTypes, Nullable`1 proposedStatusCode, CancellationToken cancellationToken)
at HotChocolate.AspNetCore.HttpPostMiddlewareBase.HandleRequestAsync(HttpContext context)
at HotChocolate.AspNetCore.HttpPostMiddlewareBase.HandleRequestAsync(HttpContext context)
at HotChocolate.AspNetCore.HttpPostMiddlewareBase.InvokeAsync(HttpContext context)
at Microsoft.AspNetCore.Builder.EndpointRouteBuilderExtensions.<>c__DisplayClass23_0.<b__1>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

Additional context

Not sure if this is the root cause, but it looks like when specifying the bug directive, "operationName" is not added to the message payload.

Chrome network traces suggest the failing query hits http://localhost:5095/graphql with the following payload:

{
  "query": "subscription test @bug(test: 123) {\r\n  bookAdded {\r\n    title\r\n  }\r\n}"
}

If you remove the "bug" directive, the following query works:

subscription test {
  bookAdded {
    title
  }
}

With the following payload payload

{
  "query": "subscription test {\r\n  bookAdded {\r\n    title\r\n  }\r\n}",
  "operationName": "test"
}

There are three issues here.

  1. Nitro stumbles over the directive and does not recognize it as subscription because of this. This is why it sends in the operation as a query with the accept header /

  2. Hot Chocolate in this case will not accept it as a subscription. There was an error in the mapping logic when we inspected the accept header.

  3. Nitro will even after a fix not expect a stream to come back. Meaning it starts buffering the request. Instead it should inspect the response content type.