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

Add CoerceResult() #836

Merged
merged 1 commit into from
Apr 8, 2021
Merged

Add CoerceResult() #836

merged 1 commit into from
Apr 8, 2021

Conversation

leebyron
Copy link
Collaborator

@leebyron leebyron commented Apr 6, 2021

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 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

@leebyron leebyron requested review from benjie, andimarek, dschafer, IvanGoncharov and a team April 6, 2021 07:06
@leebyron leebyron force-pushed the editorial-coerce-internal-value branch 3 times, most recently from 9d5ec04 to abee282 Compare April 6, 2021 07:25
@leebyron leebyron added this to the May2021 milestone Apr 6, 2021
@leebyron leebyron added the ✏️ Editorial PR is non-normative or does not influence implementation label Apr 6, 2021
@andimarek
Copy link
Contributor

I agree with that change, but I am not sure about the naming:

  • Instead of CoerceInternalValue can we name it ResultCoercion to make it clear what it is
  • internal values sounds more complicated than it is: these are the results of the Resolver. Can we not use internal values?

* 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.
Copy link
Member

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.

Copy link
Collaborator Author

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.
@leebyron leebyron force-pushed the editorial-coerce-internal-value branch from abee282 to 378fb5b Compare April 7, 2021 23:01
@leebyron leebyron changed the title Add CoerceInternalValue() Add CoerceResult() Apr 8, 2021
@leebyron leebyron requested a review from IvanGoncharov April 8, 2021 04:11
@leebyron leebyron merged commit 8d54bad into main Apr 8, 2021
@leebyron leebyron deleted the editorial-coerce-internal-value branch April 8, 2021 20:39
leebyron added a commit that referenced this pull request Apr 8, 2021
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✏️ Editorial PR is non-normative or does not influence implementation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants