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

asXXXXXXX property on a union never returning nil if selection set empty #3326

Closed
vincentisambart opened this issue Jan 24, 2024 · 4 comments · Fixed by apollographql/apollo-ios-dev#261
Assignees
Labels
bug Generally incorrect behavior codegen Issues related to or arising from code generation

Comments

@vincentisambart
Copy link
Contributor

Summary

On a union, when you have an inline fragment just getting __typename and no real field, the asMyObject property does not return nil when the type is not MyObject.

Version

1.8.0

Steps to reproduce the behavior

As an example, take this GraphQL schema:

type Query {
  main: Main!
}

type Main {
  thing: Thing!
}

union Thing = MyObject | MyError

type MyObject {
  id: Int!
}

type MyError {
  code: Int!
}

And this query:

query {
  main {
    thing {
      ... on MyObject {
        __typename
      }
    }
  }
}

If main.thing is a MyError, I would expect main.thing.asMyObject to return nil but it does not.

Note that if you add a real field to the inline fragment's selection set like the example below, you will correctly get nil if main.thing is a MyError

query {
  main {
    thing {
      ... on MyObject {
        __typename
        id
      }
    }
  }
}

Logs

No response

Anything else?

Looking at the difference of behavior, if the inline fragment's selection set is empty (other that __typename), the AsMyObject struct implements ApolloAPI.CompositeInlineFragment, but does not if the selection set has other fields in it. That changes the version of _asInlineFragment called (in the empty case func _asInlineFragment<T: CompositeInlineFragment>() -> T? gets called, in the non empty case func _asInlineFragment<T: SelectionSet>() -> T? gets called).

It looks like to me that an empty inline fragment should not implement CompositeInlineFragment, especially at is has no __mergedSources, meaning that _asInlineFragment will never return nil, but I'm not sure of the implications of this.

@vincentisambart vincentisambart added bug Generally incorrect behavior needs investigation labels Jan 24, 2024
@calvincestari
Copy link
Member

Hi @vincentisambart, thanks for raising this issue. It seems funky to have two different behaviours so we'll certainly take a look into it and try get a reproduction case.

@calvincestari
Copy link
Member

@vincentisambart - I debugged this today and I think you're correct that ApolloAPI.CompositeInlineFragment is the incorrect protocol to be conforming to. FWIW, the reason _asInlineFragment is giving the incorrect result is because the generated model incorrectly defines an empty __mergedSources list which is used to match against the returned types.

Going back a few releases it looks like this bug has existed for a while, but I've got a reproduction case now and we'll get it resolved.

@calvincestari
Copy link
Member

@vincentisambart - this has been fixed and will go out in the next release.

@vincentisambart
Copy link
Contributor Author

@calvincestari Thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Generally incorrect behavior codegen Issues related to or arising from code generation
Projects
None yet
2 participants