-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Sibling errors should not be added after propagation #1184
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
base: clarify-one-error-per-result-position
Are you sure you want to change the base?
Sibling errors should not be added after propagation #1184
Conversation
Took a stab at the implementation in Although part of me feels like an implementer with deep knowledge of the relative expected ordering of its resolvers could be theoretically confused by the missing errors such that this might belong in v17. Thoughts? |
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.
+1 to this 👍
That being said, I think this problem highlights that the current algorithms are not 100% clear on the semantics of raising errors and cancellation.
I get that resolvers might not be cancellable but it's suprising to me that graphql-js code is still executed after the execution result is received by the caller.
Ideally, there is a prompt cancellation guarantee that every callback checks for cancellation and stops processing if cancelled. Doing so in the language-neutral spec sounds like a terrible head ache though 😄 Problem for another day!
Never mind, it's an issue even (and especially) in the absence of cancellation. Well, that sucks
Putting down my thoughts from yesterday's wg before I forget everything about them. This is a significant issue but the ultimate fix is If users can update their servers, they should add proper support for This means when an error bubbles, there is no way to know which error triggered the bubbling. It's the existing behaviour. It's unfortunate but it is what it is. If you want to do better, migrate to Note: I would still change the graphql-js behaviour to not have the response change after the promise is resolved, this feels very surprising to me. |
Relevant, in terms of cancellation, merged to v17: |
@martinbonnin could you elaborate a bit more on the scenarios in which And relying on the final error on that nulled path does not work? |
I can still reproduce @benjie behaviour that the result changes after the promise has been resolved, even using
This seems suprising to me. Is that expected?
My understanding is that the problem we are trying to solve is allowing clients using graphql-toe to determine what error caused the null-bubbling without schema knowledge? #4458 is indeed a solution to that problem. My point is that it is an inferior solution to I'd rather focus our efforts and messaging on |
Yes, it needs graphql/graphql-js#4458 to solve that issue. What has been merged is eventual cancellation of the resolver cascade (in addition to triggering of passed abort signal merged separately). Just adding that your (and my) prompt cancellation aspirations, while not fulfilled in v17, have been pushed forward a bit. Creating many fine grained abort controllers to immediately cancel turned out to be too much of a performance hit… and we didn’t think enough to care about the issue of spooky additional errors after completion.
Got it.
Shouldn’t we fix this behavior for all onError modes? |
Gotcha 👍 . If I may nitpick the terminology a bit here, my point is that:
Apologies in advance for the naive question but since JS is ultimately single threaded, shouldn't checking for cancellation be reading a single per-field flag? Or is this what is actually slow?
I'm fine and happy to let it go for the current Fixing it means that some current queries will see a different response (some errors will disappear). As with every change, it might break someone's workflow. It's more work for us, new entries to process in the graphql-js changelog for everyone, all of that for something that IMO should become the "legacy" error mode. I say it's not worth the tradeoff. |
This PR is built on top of:
GraphQL.js output is not (currently) stable after an operation terminates: more errors may be added to the result after the promise has resolved!
Reproduction with `graphql` module `test.mts`
(I've formatted this output for brevity)
The reason for this: though we note in the spec that you may cancel sibling execution positions, we don't do that in GraphQL.js; and furthermore, we even process errors from the result and add them to the errors list!
This is particularly problematic for client-side "throw on error". Given this schema:
And the same spec-valid result as above:
Technically the
Test.b
field is the field that causeddata.test
to be null - it's non-nullable, so it triggered error propagation - but without looking at the schema we can't determine this.Solution: recommend that servers don't keep adding to
errors
after error propagation has occurred. This would mean:errors
after the operation has "completed"