I'm writing an API in Kotlin with the Ratpack framework, using Jackson to deserialize JSON request bodies. When I send an invalid request body, my application throws a 500 internal server error exception:
import com.google.inject.Inject
import com.mycompany.mynamespace.MyComponent
import ratpack.func.Action
import ratpack.handling.Chain
import java.util.UUID
class MyTestEndpoint @Inject constructor(
private val myComponent: MyComponent) : Action<Chain> {
override fun execute(chain: Chain) {
chain
.post { ctx ->
ctx.parse(MyParams::class.java)
.map { parsedObject -> myComponent.process(parsedObject) }
.then { ctx.response.send() }
}
}
}
data class MyParams(val borrowingId: UUID)
The exception when this endpoint is hit with an invalid request body is:
com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException: Instantiation of [simple type, class com.mycompany.mynamespace.MyParams] value failed for JSON property borrowingId due to missing (therefore NULL) value for creator parameter borrowingId which is a non-nullable type
I have a generic error handler which checks the type of Exception thrown, and returns an appropriate status. But in this case, checking for a MissingKotlinParameterException and returning 400 bad request does not make sense, because this exception may be thrown in other circumstances.
Additionally, I could add onError after the ctx.parse line, but this is going to be a large API, and implementing that in every handler doesn't follow the pattern of having a generic error handler to keep the API consistent. Is there a way to get Ratpack to throw a specific exception (something like ParseFailedException
) when the parse fails, so that I can catch it and return a 400 bad request?