On a slightly different topic, I'm also looking to...
# ktor
m
On a slightly different topic, I'm also looking to handle malformed JSON posted by a client in a correct way. I'm using the Jackson ContentConverter:
Copy code
install(ContentNegotiation) {
    jackson {
        ...
    }
}
And
call.receive<Credentials>
. However, if the submitted JSON is (say) missing a mandatory field, it blows up with a 500 response body to the client, logging:
Copy code
admin-backend     | 20:45:40.797 [nettyCallPool-4-2] ERROR Application - Error handling request: POST /login
admin-backend     | com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException: Instantiation of [simple type, class auth.dto.Credentials] value failed for JSON property password due to missing (therefore NULL) value for creator parameter password which is a non-nullable type
admin-backend     |  at [Source: (InputStreamReader); line: 4, column: 1] (through reference chain: auth.dto.Credentials["password"])
admin-backend     | 	at com.fasterxml.jackson.module.kotlin.KotlinValueInstantiator.createFromObjectWith(KotlinValueInstantiator.kt:53)
admin-backend     | 	at com.fasterxml.jackson.databind.deser.impl.PropertyBasedCreator.build(PropertyBasedCreator.java:189)
admin-backend     | 	at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:487)
admin-backend     | 	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1265)
admin-backend     | 	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:325)
admin-backend     | 	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
admin-backend     | 	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001)
admin-backend     | 	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3037)
admin-backend     | 	at io.ktor.jackson.JacksonConverter.convertForReceive(JacksonConverter.kt:39)
admin-backend     | 	at io.ktor.features.ContentNegotiation$Feature$install$3.doResume(ContentNegotiation.kt:95)
admin-backend     | 	at io.ktor.features.ContentNegotiation$Feature$install$3.invoke(ContentNegotiation.kt)
admin-backend     | 	at io.ktor.features.ContentNegotiation$Feature$install$3.invoke(ContentNegotiation.kt:50)
admin-backend     | 	at io.ktor.pipeline.PipelineContext.proceed(PipelineContext.kt:49)
admin-backend     | 	at io.ktor.pipeline.Pipeline.execute(Pipeline.kt:22)
admin-backend     | 	at io.ktor.request.ApplicationReceiveFunctionsKt.receiveOrNull(ApplicationReceiveFunctions.kt:73)
admin-backend     | 	at io.ktor.request.ApplicationReceiveFunctionsKt.receive(ApplicationReceiveFunctions.kt:62)
admin-backend     | 	at auth.AuthenticationController.handleLogin(AuthenticationController.kt:51)
However, I'd like to respond with a 400 to the client (which would be more correct) preferably with a custom response body -- is that possible?