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

Cost validator throws duplicate error for an invalid input #935

Closed
rafalp opened this issue Sep 30, 2022 Discussed in #934 · 9 comments
Closed

Cost validator throws duplicate error for an invalid input #935

rafalp opened this issue Sep 30, 2022 Discussed in #934 · 9 comments
Labels
decision needed Sounds like good idea, but will need closer scrutiny for final decision.

Comments

@rafalp
Copy link
Contributor

rafalp commented Sep 30, 2022

Discussed in #934

Originally posted by jayeshv September 30, 2022
Consider the following app

from ariadne import QueryType, ScalarType, gql, make_executable_schema
from ariadne.asgi import GraphQL
from ariadne.validation import cost_directive, cost_validator

type_defs = gql("""
    scalar MyScalar

    type Query {
      test(myInput: MyScalar!): String
    }
""")

query = QueryType()
my_scalar = ScalarType("MyScalar")

@my_scalar.value_parser
def validate_myscalar(value):
    if value == "a":
        raise ValueError("Invalid myscalar")
    return value


@query.field("test")
def resolve_hello(_, info, **kw):
    return "hello"


schema = make_executable_schema([type_defs, cost_directive], query, my_scalar)
app = GraphQL(schema, debug=False, validation_rules=[cost_validator(maximum_cost=5)])

for the following query, it generates two error objects.

query test {
  test(myInput: "a") 
}
{
  "error": {
    "errors": [
      {
        "message": "Argument 'myInput' has invalid value \"a\".\n\nGraphQL request:2:17\n1 | query test {\n2 |   test(myInput: \"a\")\n  |                 ^\n3 | }"
      },
      {
        "message": "Expected value of type 'MyScalar!', found \"a\"; Invalid myscalar",
        "locations": [
          {
            "line": 2,
            "column": 17
          }
        ]
      }
    ]
  }
}

Isn't the first error created by the cost_validator a redundant one? This duplicate error happens only with the extra validator.
ariadne version 0.16.1

jayeshv added a commit to jayeshv/ariadne that referenced this issue Sep 30, 2022
jayeshv added a commit to jayeshv/ariadne that referenced this issue Sep 30, 2022
jayeshv added a commit to jayeshv/ariadne that referenced this issue Sep 30, 2022
jayeshv added a commit to jayeshv/ariadne that referenced this issue Sep 30, 2022
jayeshv added a commit to jayeshv/ariadne that referenced this issue Sep 30, 2022
@rafalp
Copy link
Contributor Author

rafalp commented Sep 30, 2022

@jayeshv Thanks for reporting this. The reason there are two errors here is because there are two validators tat query fails against:

  • GraphQL core's query validator that validates query against schema
  • Query cost validator that expected value of one type but got another

I'm thinking that proper fix here is to only run custom validators like price check only after standard validation has passed and we know there's nothing specially funky with the query.

@jayeshv
Copy link

jayeshv commented Sep 30, 2022

I'm thinking that proper fix here is to only run custom validators like price check only after standard validation has passed and we know there's nothing specially funky with the query.

I too think that is the right fix. I made a rough fix here without knowing the entire code flow.
#936
What I did was to avoid reporting errors other than the cost one.
With this fix, it is throwing both the validation and the cost errors.

I like this behavior, but I think what you are suggesting is to remove catching that exception.

@rafalp
Copy link
Contributor Author

rafalp commented Sep 30, 2022

I'll experiment with this next week to see how we can handle this issue better. I'm not feeling comfortable about eating errors that may be caused by potentially serious issues elsewhere in validator.

@rafalp rafalp added this to the Ariadne 0.17 milestone Oct 5, 2022
@rafalp
Copy link
Contributor Author

rafalp commented Nov 15, 2022

Apologies for the delay, but I've finally investigated this. My initial idea was to do two separate validity checks, one for spec compliance checks (those test if graphql query is valid), and other for custom validators (but only if spec checks passed), but this means running AST visitor twice, and thats going to be costful for larger queries.

I am considering three approaches:

  • Don't do anything because the case here happens when there's invalid input, and its on the client to avoid this and not Ariadne to be nice.
  • Don't report errors from validators for things that are validated by built-in validator set (like PR opened for this issue).
  • Implement custom validate_query function that passes different report_error callback to built-in validators and different one to custom validators that only reports errors if errors list has no spec compliance errors.

I like option 1 the most and 2 the least. I'll see how much work it would be to implement 3.

@rafalp
Copy link
Contributor Author

rafalp commented Nov 17, 2022

Alternative solutions:

  • Make errors raised by cost validator same as ones raised by spec validators, then dedupe validation errors.
  • Make max_errors customizable on GraphQL apps so you can limit number of validation errors to say, one.

@rafalp
Copy link
Contributor Author

rafalp commented Nov 17, 2022

Punting this from 0.17, I don't feel this is big issue that should prevent the release.

@rafalp rafalp removed this from the Ariadne 0.17 milestone Nov 17, 2022
@jayeshv

This comment was marked as off-topic.

@rafalp

This comment was marked as off-topic.

@rafalp rafalp added the decision needed Sounds like good idea, but will need closer scrutiny for final decision. label Jul 21, 2023
@rafalp
Copy link
Contributor Author

rafalp commented Jan 23, 2024

Unless this is shown to be a terrible world-ending issue, I am closing this with "current approach is better than proposed alternatives" resolution.

If somebody has better idea, I'll be happy to reconsider.

@rafalp rafalp closed this as completed Jan 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
decision needed Sounds like good idea, but will need closer scrutiny for final decision.
Projects
None yet
Development

No branches or pull requests

2 participants