Hello all :wave::skin-tone-5: Making a post route...
# ktor
s
Hello all 👋🏾 Making a post route for adding a Task (name,description are only two fields and required too) 1. handling Validation using RequestValidation Plugin 2. handling Exception through StatusPages
Copy code
post {
    val newTask = getTask()
    val id = helper.createTask(newTask)
    call.respond(HttpStatusCode.Created, mapOf("id" to id))
}

private suspend fun RoutingContext.getTask(): CreateTaskType =
    runCatching { call.receive<CreateTaskType>() }.getOrElse {
        throw BadRequestException("Required fields missing ")
    }
--------------------------------------------------------------------------
validate<CreateTaskType> { task ->
            if (task.name.length > 10)
                ValidationResult.Invalid("XYz")
            else ValidationResult.Valid
        }
--------------------------------------------------------------------------
exception<RequestValidationException> { call, cause ->
            call.respond(HttpStatusCode.BadRequest, cause.reasons.joinToString())
        }
exception<BadRequestException> { call, cause ->
            call.respond(HttpStatusCode.Conflict, cause.message)
        }
My issue is everytime I make a Faulty API Call I get a BadRequestException => 409 with error Message "Required fields missing" I never get a RequestValidationException => 400 with error Message how can I prevent that and is there a better way to do such things?
b
If the request body cannot be deserialised, then it won't make it to the validate function. You can add logging to
getTask()
to see why the body cannot be deserialized.
s
when added like this
Copy code
private suspend fun RoutingContext.getTask(): CreateTaskType =
    runCatching { call.receive<CreateTaskType>() }.getOrElse { e ->
        println(e.message)
        throw BadRequestException("Required fields missing ")
    }
I can see these errors 1. Validation error Validation failed for CreateTaskType(name=Prepare Monthly Report .... 2. deserialization error Failed to convert request body to class com.example.data.model.request.CreateTaskType I am throwing the same error in both cases how can I seperate them should I use a try catch on call.receive and then handle RequestValidation exception and CannotTransformContentToTypeException seperately ?
b
yeah, best to use try-catch and handle the deserialization exceptions when the body is invalid, then allow the validation ones to pass through and get handled by the status pages plugin you could also include another clause for the deserialization exception in the status pages plugin and remove the exception handling on the receive, assuming you don't have other sources for the same exception that wouldn't create false positives
s
Got it For handling serialization errors is there a general exception I can catch ? for this lib => io.ktor:ktor-serialization-kotlinx-json the closest I can found is ContentConvertException