@@ -11,6 +11,7 @@ import com.fasterxml.jackson.databind.deser.ValueInstantiator
1111import com.fasterxml.jackson.databind.deser.ValueInstantiators
1212import com.fasterxml.jackson.databind.deser.impl.PropertyValueBuffer
1313import com.fasterxml.jackson.databind.deser.std.StdValueInstantiator
14+ import com.fasterxml.jackson.databind.exc.InvalidNullException
1415import java.lang.reflect.TypeVariable
1516import kotlin.reflect.KType
1617import kotlin.reflect.KTypeProjection
@@ -103,31 +104,32 @@ internal class KotlinValueInstantiator(
103104 } else if (strictNullChecks) {
104105 val arguments = paramType.arguments
105106
106- var paramTypeStr: String? = null
107- var itemType: KType ? = null
108-
109- if (propType.isCollectionLikeType && arguments.markedNonNullAt(0 ) && (paramVal as Collection <* >).any { it == null }) {
110- paramTypeStr = " collection"
111- itemType = arguments[0 ].type
112- }
113-
114- if (propType.isMapLikeType && arguments.markedNonNullAt(1 ) && (paramVal as Map <* , * >).any { it.value == null }) {
115- paramTypeStr = " map"
116- itemType = arguments[1 ].type
117- }
118-
119- if (propType.isArrayType && arguments.markedNonNullAt(0 ) && (paramVal as Array <* >).any { it == null }) {
120- paramTypeStr = " array"
121- itemType = arguments[0 ].type
107+ // To make the behavior the same as deserialization of each element using NullsFailProvider,
108+ // first wrapWithPath with paramVal and key.
109+ val ex = when {
110+ propType.isCollectionLikeType && arguments.markedNonNullAt(0 ) -> {
111+ (paramVal as Collection <* >).indexOf(null ).takeIf { it >= 0 }?.let {
112+ InvalidNullException .from(ctxt, jsonProp.fullName, jsonProp.type)
113+ .wrapWithPath(paramVal, it)
114+ }
115+ }
116+ propType.isMapLikeType && arguments.markedNonNullAt(1 ) -> {
117+ (paramVal as Map <* , * >).entries.find { (_, v) -> v == null }?.let { (k, _) ->
118+ InvalidNullException .from(ctxt, jsonProp.fullName, jsonProp.type)
119+ .wrapWithPath(paramVal, k.toString())
120+ }
121+ }
122+ propType.isArrayType && arguments.markedNonNullAt(0 ) -> {
123+ (paramVal as Array <* >).indexOf(null ).takeIf { it >= 0 }?.let {
124+ InvalidNullException .from(ctxt, jsonProp.fullName, jsonProp.type)
125+ .wrapWithPath(paramVal, it)
126+ }
127+ }
128+ else -> null
122129 }
123130
124- if (paramTypeStr != null && itemType != null ) {
125- throw MissingKotlinParameterException (
126- parameter = paramDef,
127- processor = ctxt.parser,
128- msg = " Instantiation of $itemType $paramType failed for JSON property ${jsonProp.name} due to null value in a $paramType that does not allow null values"
129- ).wrapWithPath(this .valueClass, jsonProp.name)
130- }
131+ // Then, wrapWithPath with this property.
132+ ex?.let { throw it.wrapWithPath(this .valueClass, jsonProp.name) }
131133 }
132134
133135 bucket[paramDef] = paramVal
0 commit comments