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

Detect dangling references in executeSelectionSet. #5830

Merged
merged 1 commit into from
Jan 23, 2020

Conversation

benjamn
Copy link
Member

@benjamn benjamn commented Jan 23, 2020

Previously, when a Reference object was encountered in the cache but the entity it referred to had been removed from the cache, we would muddle along and likely end up reporting missing fields within the object, without explicitly reporting that the object itself was missing.

With these changes, such errors will be thrown by diffQueryAgainstStore, unless returnPartialData: true is specified, just like missing field errors.

Should help with #5797, though a reproduction would be helpful.

Previously, when a Reference object was encountered in the cache but the
entity it referred to had been removed from the cache, we would muddle
along and likely end up reporting missing fields within the object,
without explicitly reporting that the object itself was missing.

Now, such errors will be thrown by diffQueryAgainstStore, unless
returnPartialData:true is specified, like missing field errors.

Should help with #5797, though a reproduction would be helpful.
!context.policies.rootTypenamesById[objectOrReference.__ref] &&
!context.store.has(objectOrReference.__ref)) {
return {
result: {},
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After playing around with various options here, including null, undefined (or no result key), and an empty object, this {} seems to be the most convenient behavior. I may be rationalizing my choice, but I think it makes sense, because a dangling reference must have pointed to an object, and now we don't know anything about the contents of that object, so it's as if it's still there but empty/useless.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using {} is definitely more convenient; I'm a tad apprehensive about using an empty object for results due to the issues we had in React Apollo around this: apollographql/react-apollo#3388. This isn't an apples to apples comparison of course, and the real problem in RA's case was that {} wasn't being used consistently. All of this to say, as long as we're using {} consistently then I think we should be okay.

@@ -198,6 +186,17 @@ export class StoreReader {
objectOrReference,
context,
}: ExecSelectionSetOptions): ExecResult {
if (isReference(objectOrReference) &&
!context.policies.rootTypenamesById[objectOrReference.__ref] &&
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check avoids reporting dangling references to ROOT_QUERY or ROOT_MUTATION, since those objects are never written explicitly by the developer, and are almost never removed from the cache after first being created. Instead, we report missing fields within those root objects.

Copy link
Member

@hwillson hwillson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great @benjamn! Just one non-blocking "musing out loud" comment.

!context.policies.rootTypenamesById[objectOrReference.__ref] &&
!context.store.has(objectOrReference.__ref)) {
return {
result: {},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using {} is definitely more convenient; I'm a tad apprehensive about using an empty object for results due to the issues we had in React Apollo around this: apollographql/react-apollo#3388. This isn't an apples to apples comparison of course, and the real problem in RA's case was that {} wasn't being used consistently. All of this to say, as long as we're using {} consistently then I think we should be okay.

@benjamn benjamn merged commit f78db36 into master Jan 23, 2020
@benjamn benjamn deleted the detect-dangling-references branch January 23, 2020 22:39
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants