Skip to content

Build unions that are only members of other unions - #887

Open
oryan-block wants to merge 1 commit into
masterfrom
bugfix/866
Open

oryan-block wants to merge 1 commit into
masterfrom
bugfix/866

Conversation

@oryan-block

Copy link
Copy Markdown
Collaborator

Fixes #866

Checklist

  • Pull requests follows the contribution guide
  • New or modified functionality is covered by tests

Description

A union that's only listed as a member of another union failed to build:

type Query {
    results: [Result!]!
}

union Result = Book | Media

union Media = Movie

No object type found with name 'Media' for union: UnionTypeDefinition{name='Result'...}

It built once some field returned Media. SchemaClassScanner#getAllObjectTypeMembersOfDiscoveredUnions only skips member unions that are already in the dictionary, and SchemaParser#getLeafUnionObjects only flattens unions the scanner found. So just skipping Media in the scanner would have moved the error to the parser.

So the scanner loop has a new step, handleNestedUnions, that adds the unions listed by discovered unions to the dictionary without a class, like handleInterfaceFieldTypes does for unions only used by interface fields. The existing union step then requires their members. The schema comes out the same as when a field returns Media: Result is Book | Movie and Media is its own union. The step only finds something when a member union isn't in the dictionary yet, which is exactly when master throws, so schemas that build today don't change.

Nested unions aren't in the spec, but they've been supported since #83 and EndToEndTest covers them, so I fixed them instead of rejecting them.

The nested union test in TypeExtensionTest had a barBaz: BarBaz field only to get around this. It's gone now, and the test has a second level of nesting, since with one level it passes even if the loop doesn't restart after the new step. Checked that it fails both without the step (the error above) and without the restart.

mvn clean verify passes on JDK 25, on JDK 25 against graphql-java 25.1, and on JDK 11. Also built the issue's schema through the public API: it fails on master with the error above, and with this change it builds and results returns both a Book and a Movie on graphql-java 26.1 and 25.1, with no warnings.

Unions that list each other still end in a StackOverflowError in getLeafUnionObjects. That's #886. Before this change, the scanner failed first when no field returned the inner union, so that case now overflows too.

The scanner only expanded a nested union that some field returned, so a union listed only as a member of another union failed with "No object type found". It now discovers those unions too, so they build the same way as when a field returns them.
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A union that's only a member of another union fails to build

1 participant