-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Add CoerceResult() #836
Add CoerceResult() #836
Conversation
9d5ec04
to
abee282
Compare
I agree with that change, but I am not sure about the naming:
|
spec/Section 6 -- Execution.md
Outdated
* Return the result of calling the internal method provided by the type | ||
system for determining the "result coercion" of {leafType} given the value | ||
{internalValue}. This internal method must return a valid value for the | ||
type or otherwise throw a field error. |
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.
I would add that "result coercion" can't be null, otherwise, we are breaking the symmetry of coercing values and completing values. It can happen in the following scenario we have scalar with parseValue
/serialize
(graphql-js terminology) so serialize
is return null, but if you pass null
as the input value of the same scalar it will be interpreted by input coercing algorithm and will never hit parseValue
.
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.
Great feedback
This factors out a step from `CompleteValue()` about "coercing" a value to a formal sub-algorithm `CoerceInternalValue()` that mirrors the language used in `ResolveAbstractType()` - both refer to "internal methods" provided for each type, which is in fact how the reference implementation applies this coercion behavior. As editorial, this provides a place to expand on the behavior and purpose as well as link back to the relevant subsection from the type system section. This also makes a *very important* clarification. The previous step read that if coercion failed then "otherwise null". This actually described a much older version of the reference implementation which did not always produce errors for failed coercion. Years back the reference implementation and the spec changed the "result coercion" subsections of all the built-in scalars to clearly state that field errors are thrown if coercion fails. This step now creates ambiguitity about which behavior is correct - returning null or throwing a field error? In practice both may be correct because of the error handling behavior - but we should be clear that the returned null is a result of that error behavior rather than it being an explicit behavior that's part of `CompleteValue()`. The new pulled out sub-algo makes it clear that the return type must be valid or a field error is produced - which is exactly the behavior described by each built-in scalar.
abee282
to
378fb5b
Compare
This factors out a step from `CompleteValue()` about "coercing" a value to a formal sub-algorithm `CoerceResult()` that mirrors the language used in `ResolveAbstractType()` - both refer to "internal methods" provided for each type, which is in fact how the reference implementation applies this coercion behavior. As editorial, this provides a place to expand on the behavior and purpose as well as link back to the relevant subsection from the type system section. This also makes a *very important* clarification. The previous step read that if coercion failed then "otherwise null". This actually described a much older version of the reference implementation which did not always produce errors for failed coercion. Years back the reference implementation and the spec changed the "result coercion" subsections of all the built-in scalars to clearly state that field errors are thrown if coercion fails. This step now creates ambiguitity about which behavior is correct - returning null or throwing a field error? In practice both may be correct because of the error handling behavior - but we should be clear that the returned null is a result of that error behavior rather than it being an explicit behavior that's part of `CompleteValue()`. The new pulled out sub-algo makes it clear that the return type must be valid or a field error is produced - which is exactly the behavior described by each built-in scalar.
This factors out a step from
CompleteValue()
about "coercing" a value to a formal sub-algorithmCoerceInternalValue()
that mirrors the language used inResolveAbstractType()
- both refer to "internal methods" provided for each type, which is in fact how the reference implementation applies this coercion behavior.As editorial, this provides a place to expand on the behavior and purpose as well as link back to the relevant subsection from the type system section.
This also makes a very important clarification. The previous step read that if coercion failed then "otherwise null". This actually described a much older version of the reference implementation which did not always produce errors for failed coercion. Years back the reference implementation and the spec changed the "result coercion" subsections of all the built-in scalars to clearly state that field errors are thrown if coercion fails. This step now creates ambiguity about which behavior is correct - returning null or throwing a field error? In practice both may be correct because of the error handling behavior - but we should be clear that the returned null is a result of that error behavior rather than it being an explicit behavior that's part of
CompleteValue()
. The new pulled out sub-algo makes it clear that the return type must be valid or a field error is produced - which is exactly the behavior described by each built-in scalar.Inspired by #780