Search code examples
kotlinktor

Catch exception in Ktor-locations if non valid route parameter


I'm new in kotlin world. So I have some problem. I'm using ktor framework and try to use ktor-locations (https://ktor.io/servers/features/locations.html#route-classes) And as example

@Location("/show/{id}")
data class Show(val id: Int)

routing {
    get<Show> { show ->
        call.respondText(show.id)
    }
}

Everything is good, when I try to get /show/1 But if route will be /show/test there is NumberFormatException, cause DefaultConversionService try to convert id to Int and can't do it. So my question is, how can I catch this exception and return Json with some error data. For example, if not using locations I can do smt like this

    routing {
        get("/{id}") {
            val id = call.parameters["id"]!!.toIntOrNull()
            call.respond(when (id) {
                null -> JsonResponse.failure(HttpStatusCode.BadRequest.value, "wrong id parameter")
                else -> JsonResponse.success(id)
            })
        }
    }

Thx for help!


Solution

  • You can do a simple try-catch in order to catch the parsing exception which is thrown when a string can not be converted to an integer.

    routing {
        get("/{id}") {
            val id = try {
                call.parameters["id"]?.toInt()
            } catch (e : NumberFormatException) {
                null
            }
            call.respond(when (id) {
                null -> HttpStatusCode.BadRequest
                else -> "The value of the id is $id"
            })
        }
    }
    

    Other way of handling exception is to use StatusPages module:

    install(StatusPages) {
        // catch NumberFormatException and send back HTTP code 400
        exception<NumberFormatException> { cause ->
            call.respond(HttpStatusCode.BadRequest)
        }
    }
    

    This should work with using Location feature. Please note that Location is experimental above ktor version 1.0.