Description
Affects: Spring Framework 5.2.7
Hello. I am trying to use the onError
functions of the Kotlin DSL coRouter
to create a global error handler on the root of my routes.
Everything was looking right at first, but after some times, we perceived some errors were not being captured by the right handler:
@Bean
fun rootRoute() = coRouter {
GET("/error") { throw IOException("") }
onError<IOException> { e, _ -> badRequest().bodyValueAndAwait("IOException") }
onError<Exception> { e, _ -> badRequest().bodyValueAndAwait("Exception") }
}
In this MWE, it seems that every time we hit "/error", and therefore have an IOException
, the exception is captured by the generic Exception
handler, instead of by the IOException
one. After some investigation, we discovered that if we switched the order of the onError
s, the correct filter start being applied.
It seems that although the error filters are arranged in the correct order inside RouterFunctionBuilder
, this ordering causes the last error handlers being verified before.
I found no documentation explaining how the onError
handlers worked when using the CoRouterFunctionDsl
and RouterFunctionDsl
, but I am almost certain this is not the desired behaviour, and if it is, we have to document it better.
As an extra example:
@Bean
fun rootRoute() = coRouter {
GET("/error") { throw IOException("") }
onError({ println("first"); false }) { e, _ -> badRequest().buildAndAwait() }
onError({ println("second"); false }) { e, _ -> badRequest().buildAndAwait() }
}
This example, when doing a GET at "/errors", prints the following lines:
second
first