@@ -11,6 +11,7 @@ import com.fasterxml.jackson.databind.deser.ValueInstantiator
11
11
import com.fasterxml.jackson.databind.deser.ValueInstantiators
12
12
import com.fasterxml.jackson.databind.deser.impl.PropertyValueBuffer
13
13
import com.fasterxml.jackson.databind.deser.std.StdValueInstantiator
14
+ import com.fasterxml.jackson.databind.exc.InvalidNullException
14
15
import java.lang.reflect.TypeVariable
15
16
import kotlin.reflect.KType
16
17
import kotlin.reflect.KTypeProjection
@@ -103,31 +104,32 @@ internal class KotlinValueInstantiator(
103
104
} else if (strictNullChecks) {
104
105
val arguments = paramType.arguments
105
106
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
122
129
}
123
130
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) }
131
133
}
132
134
133
135
bucket[paramDef] = paramVal
0 commit comments