zino-hofmann / graphql-flutter

A GraphQL client for Flutter, bringing all the features from a modern GraphQL client to one easy to use package.
https://zino-hofmann.github.io/graphql-flutter
MIT License
3.25k stars 623 forks source link

type error when graphql-ws is used for subscriptions and error is returned from server #1241

Closed ristiisa closed 2 years ago

ristiisa commented 2 years ago

GraphQLSocketMessage.parse seems to throw when server responds to a subscription with an error

GraphQLSocketMessage.parse (~\.pub-cache\hosted\pub.dartlang.org\graphql-5.1.2-beta.4\lib\src\links\websocket_link\websocket_messages.dart:62)
_MapStream._handleData (dart:async/stream_pipe.dart:213)
_ForwardingStreamSubscription._handleData (dart:async/stream_pipe.dart:153)
_rootRunUnary (dart:async/zone.dart:1399)
_CustomZone.runUnary (dart:async/zone.dart:1300)
_CustomZone.runUnaryGuarded (dart:async/zone.dart:1209)
_BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339)
_BufferingStreamSubscription._add (dart:async/stream_impl.dart:271)
_SyncBroadcastStreamController._sendData.<anonymous closure> (dart:async/broadcast_stream_controller.dart:385)
_BroadcastStreamController._forEachListener (dart:async/broadcast_stream_controller.dart:322)
_SyncBroadcastStreamController._sendData (dart:async/broadcast_stream_controller.dart:384)
_BroadcastStreamController.add (dart:async/broadcast_stream_controller.dart:244)
_AsBroadcastStreamController.add (dart:async/broadcast_stream_controller.dart:474)
_rootRunUnary (dart:async/zone.dart:1399)
_CustomZone.runUnary (dart:async/zone.dart:1300)
_CustomZone.runUnaryGuarded (dart:async/zone.dart:1209)
_BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339)
_BufferingStreamSubscription._add (dart:async/stream_impl.dart:271)
_ForwardingStreamSubscription._add (dart:async/stream_pipe.dart:123)
_HandleErrorStream._handleData (dart:async/stream_pipe.dart:253)

message:

{"id":"9518f6a5-cd3b-4dab-a656-81f13c2c88f7","type":"error","payload":[{"message":"Cannot query field \"XXX\" on type \"YYY\".","locations":[{"line":123,"column":123}]}]}

Flutter (Channel stable, 3.3.3, on macOS 11.6.2 20G314 darwin-x64, locale en-EE) graphql: ^5.1.2-beta.4

backend side:

graphql-ws@5.11.2
ws@8.8.1
vincenzopalazzo commented 2 years ago

I'm pretty sure that you are using the wrong protocol, but without code is hard to reproduce!

Waiting for code to reproduce it

ristiisa commented 2 years ago
import { GraphQLSchema, GraphQLObjectType, GraphQLString } from 'graphql';
import { WebSocketServer } from 'ws';
import { useServer } from 'graphql-ws/lib/use/ws';

const schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    name: 'Query',
    fields: {
      hello: {
        type: GraphQLString,
        resolve: () => 'world',
      },
    },
  }),
  subscription: new GraphQLObjectType({
    name: 'Subscription',
    fields: {
      greetings: {
        type: GraphQLString,
        subscribe: async function* () {
          for (const hi of ['Hi', 'Bonjour', 'Hola', 'Ciao', 'Zdravo']) {
            yield { greetings: hi };
          }
        }
      }
    }
  })
});

const server = new WebSocketServer({
  port: 4000,
  path: '/graphql',
});

useServer({ schema }, server);

console.log('Listening to port 4000');
ws_test() {
    var client = GraphQLClient(
      cache: GraphQLCache(partialDataPolicy: PartialDataCachePolicy.accept),
      defaultPolicies: DefaultPolicies(
        query: Policies.safe(
          FetchPolicy.noCache,
          ErrorPolicy.none,
          CacheRereadPolicy.mergeOptimistic,
        ),
        subscribe: Policies.safe(
          FetchPolicy.noCache,
          ErrorPolicy.none,
          CacheRereadPolicy.mergeOptimistic,
        ),
        mutate: Policies.safe(
          FetchPolicy.noCache,
          ErrorPolicy.none,
          CacheRereadPolicy.mergeOptimistic,
        ),
        watchMutation: Policies.safe(
          FetchPolicy.noCache,
          ErrorPolicy.none,
          CacheRereadPolicy.mergeOptimistic,
        ),
        watchQuery: Policies.safe(
          FetchPolicy.noCache,
          ErrorPolicy.none,
          CacheRereadPolicy.mergeOptimistic,
        )
      ),
      link: WebSocketLink("ws://localhost:4000/graphql", subProtocol: GraphQLProtocol.graphqlTransportWs),
    ).subscribe(SubscriptionOptions(
      document: gql("subscription { greeting }"),
    )).listen((event) {
      print(event.data);
    })
    ..onError((error, stack) {
      print([error, stack]);
    })
    ..onDone(() => print("done"));
}
vincenzopalazzo commented 2 years ago

what protocol graphql-ws has?

ristiisa commented 2 years ago

graphql-transport-ws

ristiisa commented 2 years ago

req: image

rsp: image