-
Notifications
You must be signed in to change notification settings - Fork 2k
Test: Missing subscription field should not be an "internal error" #1106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
2c5a399
to
c78e33f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When trying to execute a subscription with an invalid selection set, I think we should throw when attempting to create the subscription.
EDIT: I used "throw" too loosely. I meant in accordance with how we want to handle 400-class errors elsewhere. My impressions is that returning an emptyAsyncIterator feels too subtle for an error case.
@@ -347,7 +346,7 @@ describe('Subscription Initialization Phase', () => { | |||
); | |||
}); | |||
|
|||
it('throws an error for unknown root field', async () => { | |||
it('unknown field should result in closed subscription', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think asking for an unknown field is a 400-class error code (something about the request was malformed). In that case, I think the await createSubscription
call should throw.
My reasonings is that if we don't throw there, we'll have a subscription that is in the closed state, which does not communicate that the request was invalid or what was wrong with it.
src/subscription/subscribe.js
Outdated
); | ||
|
||
if (!fieldDef) { | ||
return resolve(emptyAsyncIterator()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't feel like the right return value for a missing field case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would be a better one? Presuming an error becomes the domain of a validation step, we should produce something
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In https://github.com/facebook/graphql/blob/master/spec/Section%206%20--%20Execution.md#executing-requests we describe Subscribe
as the async variant of ExecuteQuery
. For ExecuteQuery
, the spec says, "Return an unordered map containing {data} and {errors}."while Subscribe
says Return {responseStream}.
. Perhaps we should update these to be more similar, for example, 'Subscribe` could resolve to an unordered map of {responseStream} and {errors}.
Also remember that "subscribe" is the second half of a presumed "validate & subscribe" path. I think the missing piece is a validation rule that a subscription is well-formed. There is symmetry if my proposed behavior to My suggestion here is that the "subscribe" operation is the wrong place for this error, it should instead be caught earlier during validation, and instead this operation should be durable to the malformed input |
http://facebook.github.io/graphql/draft/#sec-Subscription-Operation-Definitions seems to handle this case, validation errors are typically reported as 400-level.
I think the flow types we've defined more closely refer to a responseStream or a single error response payload |
557a773
to
e09e823
Compare
A remaining issue with subscriptions is attempting to subscribe to a missing field. The existing implementation creates an internal error which is an improper blame since there is no possibility to fix it internally - it is an issue with the query. Since there is no clear consistent behavior relative to query/mutation operations (which simply skip over unknown fields), and the corner-case where this occurs should deal with the error - this changes the internal error to an external yielded GraphQL error. Note: we still require a spec change since there is an ambiguity of this exact scenario.
e09e823
to
aac2a5e
Compare
Updated description and commit to reflect "400" level error rather than current "500" level error after offline review with @robzhu |
Test: Missing subscription field should not be an "internal error"
A remaining issue with subscriptions is attempting to subscribe to a missing field. The existing implementation creates an internal error which is an improper blame since there is no possibility to fix it internally - it is an issue with the query.
Since there is no clear consistent behavior relative to query/mutation operations (which simply skip over unknown fields), and the corner-case where this occurs should deal with the error - this changes the internal error to an external yielded GraphQL error.
Note: we still require a spec change since there is an ambiguity of this exact scenario.