I’m using kotlinx.serialization, and when I receiv...
# ktor
s
I’m using kotlinx.serialization, and when I receive a JSON object that has some unknown keys to my model a 500 is sent back automatically. I don’t want to use
ignoreUnknownKeys = true
. And I am using the
post("path") { myType: MyType -> //code }
syntax. I could potentially change this with
Copy code
val login: Login = try {
    call.receive()
} catch (e: SerializationException) {
    return@post call.respondWith(Response.badRequest(InvalidInput))
}
Or even
val login: Login = call.receiveOrNull() ?: return@post call.respondWith(Response.badRequest(InvalidInput))
But I don’t necessarily like this if there is an alternative. How would I deal with this? Can I create an interceptor that catches all SerializationExceptions? Something else? Is my proposed solution the only way? I really do want to use the typed version of the post() method if possible.
c
You can catch specific exceptions (using the status page plugin), but I don't know if it's a good idea
a
It's a good idea to use StatusPages plugin for this case because one of its responsibilities is to map exceptions to responses. Here is an example:
Copy code
fun main(args: Array<String>) {
    embeddedServer(Netty, port = 7070, host = "0.0.0.0") {
        install(StatusPages) {
            exception<kotlinx.serialization.SerializationException> {
                call.respondText(status = HttpStatusCode.BadRequest, text = it.message ?: "")
            }
        }

        install(ContentNegotiation) {
            json()
        }

        routing {
            post("/") { data: Req ->
                call.respondText { "x: ${data.x}" }
            }
        }
    }.start(wait = true)
}

@Serializable
data class Req(val x: Int)
s
Awesome, so this is the way to handle this properly. And maybe consider the
receiveOrNull()
idea for more specialized handling of specific cases. Thank you! And thanks for the code snippet too. The documentation was super easy to follow to install the StatusPages myself too 😊