-
Notifications
You must be signed in to change notification settings - Fork 656
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
A request with any enum having rawValue = null
hangs forever
#5901
Comments
Hi 👋 Many thanks for the detailed issue and the kind words ❤️ .
Apollo's own @BoD built most of the Apollo IJ plugin, which depends on the IntelliJ GraphQL plugin for shared functionality.
Looks like you're using Java codegen? ( apollo {
service("service") {
generateKotlinModels.set(true)
sealedClassesForEnumsMatching.set(listOf(".*"))
}
} They should make it impossible to pass |
Using the Kotlin generated code does indeed make it impossible to pass I'm using the latest version but the generated enum class doesn't appear to have the Is there a problem preventing the generated enum class from making the constructor private? |
I'm also curious how |
Rigth 👍
Indeed, this is only for Kotlin, and only for the SNAPSHOTs versions
Excellent question. IIRC there was some concern that some advanced use cases could still want to send unknown (to the client) enums (that would be known by the server). This could happen for an an example if the enum is passed "out of band" to an older app. You can read https://slack-chats.kotlinlang.org/t/16930109/apollo-kotlin-generates-an-unknown-entry-in-all-enums-to-be- for some background although I'm not sure what the ultimate decision was (if there was one). Maybe @BoD will remember.
Correct 👍 All in all, we should add a non-null assertion for Java codegen. Whether we can do better while still keeping the constructor accessible is not clear to me. Java doesn't have |
Thanks for the answers.
I support this. Seems like the simplest solution going forward. |
What do you think of:
2 and 3 are breaking changes but it's probably for the better |
Wouldn't that prevent users to use a custom |
|
Gotcha 👍 Perfect plan ✅ |
Made the change in #5904 which will be included in the next beta release of v4. The related change has also be made in the generated Kotlin enums when using sealed classes: now |
Fix is released in 4.0.0-beta.7 |
Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo Kotlin usage and allow us to serve you better. |
Version
4.0.0-beta.6
Summary
Enums defined in the provided graphQL schema are defined as pseudo-enums, actually classes wrapping a String member called
rawValue
. While it's possible to use the provided enum constants from the class, you can also create your own, possibly passing innull
.Example enum in the graphql schema:
Generated
StatusEnum
class:A good usage of StatusEnum would be to use the constants such as
StatusEnum.GOOD
, orStatusEnum.BAD
. Another valid use ofStatusEnum
would be to parse the string"GOOD"
intoStatusEnum.GOOD
usingStatusEnum.safeValueOf("GOOD")
or evennew StatusEnum("GOOD")
.An invalid, yet allowed, usage of StatusEnum is to pass in
null
to the constructor:new StatusEnum(null)
. This isn't checked for invalidity at any point, even up through making the GraphQL call:When used in conjunction with
Rx3Apollo.single(...).blockingGet()
, a NullPointerException is thrown in another thread when attempting to serialize this value:Because the serialization exception happens in a different thread, but we're using
Rx3Apollo.single(...).blockingGet()
to block until the request finishes, the result is that the current thread hangs forever.Obviously, this is an invalid use of the generated enum -- or maybe it's valid and
null
should be the resulting serialized value. In any case, it would be much more useful to have the library do something (either usenull
or surface the exception to the calling thread) rather than just hang forever.Possible Solutions
if (rawValue == null) throw new NullPointerException()
in the constructor would suffice.rawValue
is null, and if so, serialize to JSON asnull
-- this is in caserawValue=null
is a valid state and should be allowed.Just some ideas. I have never contributed to this library and TBH I'm still figuring out how best to use it. Please let me know the desired path forward.
Steps to reproduce the behavior
I've created a repo to reproduce this behavior in the simplest possible way: https://github.com/japhib/apollo-null-enum-test
To reproduce the bug, simply run
./gradlew test
and observe that the testTestMain.testNullEnumHangs()
times out after the configured 30 second timeout.Key parts:
null
as therawValue
for the enum constructor:Logs
See above.
thanks!
Just wanted to say, thanks for this library! For the most part it has been great to use and has solved the problem of using GraphQL from Java in a rather elegant way. The code generation is nice to work with and the IntelliJ plugin (maybe maintained by this org?) is also very convenient to work with.
The text was updated successfully, but these errors were encountered: