Description
Describe the bug
OneOf values seem to get validated lazily when a DataFetcher accesses its arguments. This allows OneOf types to be used incorrectly and to not raise a validation error, which can happen when using a PropertyDataFetcher or a DataFetcher that ignores its arguments.
This seems not in keeping with section 6.11 of the spec, which requires that all validation happen before execution:
only requests which pass all validation rules should be executed. If validation errors are known, they should be reported in the list of “errors” in the response and the request must fail without execution
I was expecting OneOf value validation to be implemented in graphql.validation.rules and to be handled earlier, at the same stage as rules like ArgumentsOfCorrectType
. I'd be interested in implementing a rule to do this, though I wanted to first check to see if this was a deliberate decision or if there's something I'm missing.
To Reproduce
Here's a PR with a test case that uses a OneOf value with multiple keys. The test case fails because no validation error is raised.
def "rejects invalid OneOf values before invoking data fetchers"() {
def sdl = '''
type Query {
f(arg: OneOf): Boolean
}
input OneOf @oneOf { a: Int b: Int }
'''
def graphQLSchema = TestUtil.schema(sdl)
def graphQL = GraphQL.newGraphQL(graphQLSchema).build()
when:
def er = graphQL.execute('{ f(arg : {a: 0, b: 0}) }')
then:
!er.errors.isEmpty()
er.errors[0].message == "Exception while fetching data (/f) : Exactly one key must be specified for OneOf type 'OneOf'."
}