diff --git a/lib/graphql/schema/subscription.rb b/lib/graphql/schema/subscription.rb index a662ecc31d..8f1c07971c 100644 --- a/lib/graphql/schema/subscription.rb +++ b/lib/graphql/schema/subscription.rb @@ -173,8 +173,12 @@ def self.topic_for(arguments:, field:, scope:) # later in execution. # @return [void] def write_subscription - @subscription_written = true - context.schema.subscriptions.write_subscription(context.query, [event]) + if subscription_written? + raise GraphQL::Error, "`write_subscription` was called but `#{self.class}#subscription_written?` is already true. Remove a call to `write subscription`." + else + @subscription_written = true + context.schema.subscriptions.write_subscription(context.query, [event]) + end nil end diff --git a/spec/graphql/schema/subscription_spec.rb b/spec/graphql/schema/subscription_spec.rb index 06cb73952b..9bccec64dc 100644 --- a/spec/graphql/schema/subscription_spec.rb +++ b/spec/graphql/schema/subscription_spec.rb @@ -722,7 +722,14 @@ def subscribe class DirectWrite < ImplicitWrite type String + def subscribe + write_subscription + super + end + end + class DirectWriteTwice < DirectWrite + type String def subscribe write_subscription super @@ -732,6 +739,8 @@ def subscribe class Subscription < GraphQL::Schema::Object field :direct, subscription: DirectWrite field :implicit, subscription: ImplicitWrite + field :direct_twice, subscription: DirectWriteTwice + field :with_payload, subscription: DirectWriteWithPayload end use WriteCheckSubscriptions.new @@ -751,5 +760,12 @@ class Subscription < GraphQL::Schema::Object assert_equal [1], res.context[:written_events].map(&:size) assert_equal false, res.context.namespace(:subscriptions)[:subscriptions].values.first.subscription_written? end + + it "raises if write_subscription is called twice" do + err = assert_raises GraphQL::Error do + DirectWriteSchema.execute("subscription { directTwice }") + end + assert_equal "`write_subscription` was called but `DirectWriteSchema::DirectWriteTwice#subscription_written?` is already true. Remove a call to `write subscription`.", err.message + end end end