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

Improve default ValidationRule failure behavior #659

Closed
benasher44 opened this issue May 29, 2024 · 10 comments
Closed

Improve default ValidationRule failure behavior #659

benasher44 opened this issue May 29, 2024 · 10 comments
Labels

Comments

@benasher44
Copy link

benasher44 commented May 29, 2024

We were caught by surprise that when using the rules as GraphQL validation rules, the default behavior is to throw the error. At least for Apollo Server, this results in a 500-style crash. I would have expected the error to propagate through the passed graphql.ValidationContext. It's easy enough to write default configuration that does this:

  propagateOnRejection: false,
  onReject: [
    (context, error) => {
      context?.reportError(error);
    },
  ],

As a future breaking change, it might be preferred to replace propagateOnRejection be with something like rejectionPropagationMode: "context" | "throw" | "none", where "context" is the default (results in the appropriate 4xx error, when propagated through the graphql.ValidationContext)

@nullswan
Copy link
Member

If you push the error to the context, the query won't be canceled. Instead, it will still be processed and go through the entire flow until it reaches the next step in the GraphQL parser, @benasher44. If that's the expected behavior, then this approach is fine, but it won't prevent the query from consuming resources.

Let me know how I can help further.

@benasher44
Copy link
Author

benasher44 commented May 29, 2024

Are you sure? I would imagine this is where server implementations could break from the spec, but looking at this spec (hopefully looking at the right version) (section 6.1.1), only operations that pass all validation rules should be executed.

@benasher44
Copy link
Author

Specifically this part makes me hopeful that servers really shouldn't do this:

If validation errors are known, they should be reported in the list of “errors” in the response and the request must fail without execution.

@benasher44
Copy link
Author

FWIW, graphql-js's reference implementation seems to honor this: https://github.com/graphql/graphql-js/blob/e15c3ec4dc21d9fd1df34fe9798cadf3bf02c6ea/src/graphql.ts#L122

@nullswan
Copy link
Member

nullswan commented May 29, 2024

FWIW, graphql-js's reference implementation seems to honor this: https://github.com/graphql/graphql-js/blob/e15c3ec4dc21d9fd1df34fe9798cadf3bf02c6ea/src/graphql.ts#L122

Indeed, request cancellation is not supported.

Parse, return errors, Validate, return errors.

But that is too late.
Let's take maxTokens as an example, once you reached n tokens, you want to stop the processing, otherwise, you are vulnerable to CPU overloading.

To be more precise, the problem is the parser in most of overloading cases.

@benasher44
Copy link
Author

benasher44 commented May 29, 2024

I see! Yeah in that case, I understand. I think my comment still stands. What you're getting from this package is a ValidationRule, which implies hook-ability into the graphql validation phase. I think it's reasonable to assume that if you have a ValidationRule, it's going to report errors to graphql-js the expected way, when used as one.

In the case of maxTokens (and possibly others), afaik you'll need to take extra care to use the rule before graphql gets to parse the document. In that case, I think throwing makes sense (no longer trying to fit into graphql's validation step), since the implementation will be highly server-specific (i.e. depends on how/where you hook into parsing) (e.g. might attempt to validate max tokens in express before the express json handler decodes the string).

@benasher44
Copy link
Author

In any case, improvements to the API here might provide a good way to educate users on the tradeoffs

@nullswan
Copy link
Member

I'll be happy to review a merge request about this topic ! 🥳

Copy link
Contributor

This issue is stale because it has been open for 30 days with no activity.

@github-actions github-actions bot added the stale label Jun 29, 2024
Copy link
Contributor

This issue was closed because it has been inactive for 14 days since being marked as stale.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants