Skip to content
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

original execute should throw if defer/stream directives are present #3722

Merged
merged 3 commits into from
Dec 29, 2022

Conversation

yaacovCR
Copy link
Contributor

@yaacovCR yaacovCR commented Sep 2, 2022

Currently, when the defer/stream directives are not present in the schema, defer/stream will not be triggered, and so the directives will be ignored even when used with the original function.

But -- if the directives are in the schema, the original functions will sometimes throw (if the first result from execute is synchronous), but sometimes return maps with errors (when the first result from execute is async or when any (sync or async) subscribe payload has incremental results.

This PR just aligns the behavior in terms of throwing or returning a map with errors. We really shouldn't return a map with errors after execution has begun.

I think another viable alternative that potentially makes more sense is to have the original execute and subscribe functions ignore the directives. To enable the experimental behavior, you would need to have the directives in the schema and use the experimental functions.

@glasser @robrichard @IvanGoncharov @n1ru4l

@netlify
Copy link

netlify bot commented Sep 2, 2022

Deploy Preview for compassionate-pike-271cb3 ready!

Name Link
🔨 Latest commit 3b00b01
🔍 Latest deploy log https://app.netlify.com/sites/compassionate-pike-271cb3/deploys/63ac8fe4c17efc0008ea99dd
😎 Deploy Preview https://deploy-preview-3722--compassionate-pike-271cb3.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@yaacovCR yaacovCR changed the title original execute and subscribe should throw if defer/stream are used original execute and subscribe should throw if defer/stream are used Sep 2, 2022
@github-actions
Copy link

github-actions bot commented Sep 2, 2022

Hi @yaacovCR, I'm @github-actions bot happy to help you with this PR 👋

Supported commands

Please post this commands in separate comments and only one per comment:

  • @github-actions run-benchmark - Run benchmark comparing base and merge commits for this PR
  • @github-actions publish-pr-on-npm - Build package from this PR and publish it on NPM

@yaacovCR yaacovCR added the PR: bug fix 🐞 requires increase of "patch" version number label Sep 2, 2022
@glasser
Copy link
Contributor

glasser commented Sep 2, 2022

I like the idea of being more consistent, but maybe this is consistent in the wrong direction and it would be more informative to take the choice that is more likely to push the error to the client? Not sure.

Currently, when the defer/stream directives are not present in the schema, defer/stream will not be triggered, and so the directives will be ignored even when used with the original function.

Just to be clear: this is a statement about execute specifically: such operations should still fail validation, no?

@yaacovCR
Copy link
Contributor Author

yaacovCR commented Sep 3, 2022

@glasser correct, they should fail validation if not in schema.

In terms of this behavior being more consistent, but not ideal, maybe it would make sense in v16 to try something along that line, like providing a temporary validation rule that outlaws the use of these directives that could be used if you're not using the experimental version. Maybe providing an experimental validate where only the original validate includes this rule?

Otherwise, the original execute could just ignore the directives.
I think that both of those options would be better than what we have now, but at least with this PR, we are consistently throwing.

I don't think execute should return a map with errors once execution has begun. It might sound a bit dogmatic, but I think that way of thinking also exposes that the "error" that is occurring is not actually a field error and should be handled earlier or differently.

@yaacovCR
Copy link
Contributor Author

yaacovCR commented Sep 6, 2022

An alternative to this is #3727.

@yaacovCR
Copy link
Contributor Author

@robrichard @IvanGoncharov

It looks to me like this PR is essentially the behavior we were shooting for.

Rebased and ready to review.

@yaacovCR yaacovCR added PR: breaking change 💥 implementation requires increase of "major" version number and removed PR: bug fix 🐞 requires increase of "patch" version number labels Sep 28, 2022
@yaacovCR yaacovCR changed the title original execute and subscribe should throw if defer/stream are used original execute and subscribe should throw if defer/stream directives are present Sep 28, 2022
Copy link
Contributor

@glasser glasser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like it would cause confusion for any users who are using GraphQL execution indirectly via software like Apollo Server/GraphQL Yoga/graphql-helix/etc rather than calling execute directly. A user-level change (adding a line to their schema) tells them to change a function that they aren't actually calling directly.

I'm not saying I object to the basic concept of throwing an error in this case (though I'm a bit skeptical) but I do wonder if the error message could be more actionable in the common case where the person putting together the data (schema) is not the person calling the named function.

We cannot return a map with only errors after execution has begun. Instead, we must throw or return a rejected promise.
@yaacovCR yaacovCR changed the title original execute and subscribe should throw if defer/stream directives are present original execute should throw if defer/stream directives are present Dec 28, 2022
@yaacovCR
Copy link
Contributor Author

This seems like it would cause confusion for any users who are using GraphQL execution indirectly via software like Apollo Server/GraphQL Yoga/graphql-helix/etc rather than calling execute directly. A user-level change (adding a line to their schema) tells them to change a function that they aren't actually calling directly.

I'm not saying I object to the basic concept of throwing an error in this case (though I'm a bit skeptical) but I do wonder if the error message could be more actionable in the common case where the person putting together the data (schema) is not the person calling the named function.

@glasser -- I made the error message a bit more generic, without reference to the exact method by which to enable experimental execution features. I am not sure if this is better, definitely open to suggestions for the exact language.

@IvanGoncharov
Copy link
Member

@yaacovCR Thanks for iterating on this.
If we will have issues with an error message we can definitely improve it in subsequent PRs.

@IvanGoncharov IvanGoncharov merged commit 522f495 into graphql:main Dec 29, 2022
@glasser
Copy link
Contributor

glasser commented Jan 4, 2023

Just want to note that this PR does not affect executeSync, which appears to be able to execute queries which don't contain defer/stream against schemas that do contain defer/stream. On the one hand this is a bit of a weird inconsistency for execute to be banned but executeSync to work, but breaking executeSync here would break introspectionFromSchema which would be quite bad.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PR: breaking change 💥 implementation requires increase of "major" version number
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants