From d2ef4b5a6106e39e077d8f314363bebc6ef34e58 Mon Sep 17 00:00:00 2001 From: Eric Cochran Date: Sun, 7 Jan 2018 11:07:56 -0800 Subject: [PATCH] Clarify error for non-null Kotlin properties. (#376) Instead of throwing an InvocationTargetException. --- .../com/squareup/moshi/KotlinJsonAdapter.kt | 11 +++++++- .../squareup/moshi/KotlinJsonAdapterTest.kt | 26 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/kotlin/src/main/java/com/squareup/moshi/KotlinJsonAdapter.kt b/kotlin/src/main/java/com/squareup/moshi/KotlinJsonAdapter.kt index d0374f9..3c8bfd9 100644 --- a/kotlin/src/main/java/com/squareup/moshi/KotlinJsonAdapter.kt +++ b/kotlin/src/main/java/com/squareup/moshi/KotlinJsonAdapter.kt @@ -81,6 +81,9 @@ internal class KotlinJsonAdapter( "Required value ${constructor.parameters[i].name} missing at ${reader.path}") } values[i] = null // Replace absent with null. + } else if (values[i] == null && !constructor.parameters[i].type.isMarkedNullable) { + throw JsonDataException("Non-null value ${constructor.parameters[i].name} " + + "was null at ${reader.path}") } } @@ -89,7 +92,13 @@ internal class KotlinJsonAdapter( // Set remaining properties. for (i in constructorSize until bindings.size) { - bindings[i]!!.set(result, values[i]) + val binding = bindings[i]!! + val value = values[i] + if (value == null && !binding.property.returnType.isMarkedNullable) { + throw JsonDataException("Non-null value ${binding.property.name} " + + "was null at ${reader.path}") + } + binding.set(result, value) } return result diff --git a/kotlin/src/test/java/com/squareup/moshi/KotlinJsonAdapterTest.kt b/kotlin/src/test/java/com/squareup/moshi/KotlinJsonAdapterTest.kt index 0b24e93..a298d89 100644 --- a/kotlin/src/test/java/com/squareup/moshi/KotlinJsonAdapterTest.kt +++ b/kotlin/src/test/java/com/squareup/moshi/KotlinJsonAdapterTest.kt @@ -133,6 +133,32 @@ class KotlinJsonAdapterTest { class RequiredValueAbsent(var a: Int = 3, var b: Int) + @Test fun nonNullConstructorParameterCalledWithNullFailsWithJsonDataException() { + class Data(val a: String) + val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build() + val jsonAdapter = moshi.adapter(Data::class.java) + + try { + jsonAdapter.fromJson("{\"a\":null}") + fail() + } catch (expected: JsonDataException) { + assertThat(expected).hasMessage("Non-null value a was null at \$") + } + } + + @Test fun nonNullPropertySetToNullFailsWithJsonDataException() { + class Data { var a: String = "" } + val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build() + val jsonAdapter = moshi.adapter(Data::class.java) + + try { + jsonAdapter.fromJson("{\"a\":null}") + fail() + } catch (expected: JsonDataException) { + assertThat(expected).hasMessage("Non-null value a was null at \$") + } + } + @Test fun duplicatedValue() { val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build() val jsonAdapter = moshi.adapter(DuplicateValue::class.java)