From 032afeb462160f2b3f227646b72894ac62b03bcc Mon Sep 17 00:00:00 2001 From: Eric Cochran Date: Wed, 8 May 2024 08:09:48 -0400 Subject: [PATCH] Fix error message when missing primary constructor. Without this, the error message was ClassJsonAdapter saying you need to install a Kotlin adapter factory. --- .../kotlin/reflect/KotlinJsonAdapterTest.kt | 18 ++++++++++++++++++ .../kotlin/reflect/KotlinJsonAdapterFactory.kt | 9 ++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/moshi-kotlin-tests/src/test/kotlin/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapterTest.kt b/moshi-kotlin-tests/src/test/kotlin/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapterTest.kt index b6a742307..dc4b44901 100644 --- a/moshi-kotlin-tests/src/test/kotlin/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapterTest.kt +++ b/moshi-kotlin-tests/src/test/kotlin/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapterTest.kt @@ -1074,6 +1074,24 @@ class KotlinJsonAdapterTest { sealed class SealedClass + @Test fun requirePrimaryConstructor() { + val moshi: Moshi = Moshi.Builder() + .add(KotlinJsonAdapterFactory()) + .build() + try { + moshi.adapter(SubClass::class.java) + } catch (e: IllegalArgumentException) { + assertThat(e).hasMessageThat() + .contains("Cannot reflectively serialize class without the primary constructor") + } + } + + open class SuperClass + + class SubClass : SuperClass { + constructor() : super() + } + private fun mapWildcardsParameterizedTest(type: Class, json: String, value: T) { // Ensure the map was created with the expected wildcards of a Kotlin map. val fieldType = type.getDeclaredField("map").genericType diff --git a/moshi-kotlin/src/main/java/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapterFactory.kt b/moshi-kotlin/src/main/java/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapterFactory.kt index 902499583..50e3c5465 100644 --- a/moshi-kotlin/src/main/java/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapterFactory.kt +++ b/moshi-kotlin/src/main/java/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapterFactory.kt @@ -213,6 +213,9 @@ public class KotlinJsonAdapterFactory : JsonAdapter.Factory { // Fall back to a reflective adapter when the generated adapter is not found. } + require(!rawType.isAnonymousClass) { + "Cannot serialize anonymous class ${rawType.name}" + } require(!rawType.isLocalClass) { "Cannot serialize local class or object expression ${rawType.name}" } @@ -230,7 +233,11 @@ public class KotlinJsonAdapterFactory : JsonAdapter.Factory { "Cannot reflectively serialize sealed class ${rawType.name}. Please register an adapter." } - val constructor = rawTypeKotlin.primaryConstructor ?: return null + val constructor = rawTypeKotlin.primaryConstructor + requireNotNull(constructor) { + "Cannot reflectively serialize class without the primary constructor ${rawType.name}." + + " Please register an adapter." + } val parametersByName = constructor.parameters.associateBy { it.name } constructor.isAccessible = true