diff --git a/internal/exec/subscribe.go b/internal/exec/subscribe.go index 6c7ea1a0..16cae69c 100644 --- a/internal/exec/subscribe.go +++ b/internal/exec/subscribe.go @@ -55,6 +55,10 @@ func (r *Request) Subscribe(ctx context.Context, s *resolvable.Schema, op *query } }() + if f == nil { + return sendAndReturnClosed(&Response{Errors: []*errors.QueryError{err}}) + } + if err != nil { if _, nonNullChild := f.field.Type.(*common.NonNull); nonNullChild { return sendAndReturnClosed(&Response{Errors: []*errors.QueryError{err}}) diff --git a/subscription_test.go b/subscription_test.go index 5b8c56ba..96649d94 100644 --- a/subscription_test.go +++ b/subscription_test.go @@ -56,6 +56,10 @@ func (r *helloSaidResolver) HelloSaid(ctx context.Context) (chan *helloSaidEvent return c, nil } +func (r *rootResolver) OtherField(ctx context.Context) <-chan int32 { + return make(chan int32) +} + func (r *helloSaidEventResolver) Msg() (string, error) { return r.msg, r.err } @@ -416,6 +420,36 @@ func TestRootOperations_validSubscriptionSchema(t *testing.T) { }) } +func TestError_multiple_subscription_fields(t *testing.T) { + gqltesting.RunSubscribes(t, []*gqltesting.TestSubscription{ + { + Name: "Explicit schema without subscription field", + Schema: graphql.MustParseSchema(` + schema { + query: Query + subscription: Subscription + } + type Query { + hello: String! + } + type Subscription { + helloSaid: HelloSaidEvent! + otherField: Int! + } + type HelloSaidEvent { + msg: String! + } + `, &rootResolver{helloSaidResolver: &helloSaidResolver{upstream: closedUpstream(&helloSaidEventResolver{msg: "Hello world!"})}}), + Query: `subscription { helloSaid { msg } otherField }`, + ExpectedResults: []gqltesting.TestResponse{ + { + Errors: []*qerrors.QueryError{qerrors.Errorf("can subscribe to at most one subscription at a time")}, + }, + }, + }, + }) +} + const schema = ` schema { subscription: Subscription,