Search code examples
spring-bootkotlinkotlin-coroutinesspring-webclient

What would be the proper way to pass custom exception from Kotlin Webclient awaitExchange Lambda function to web controller?


Working on a new microservice that's using reactive WebClient to call another microservice.

Here is what I have:

Controller.kts

@GetMapping(["/books/{id}"], produces = [MediaType.APPLICATION_JSON_VALUE])
suspend fun getBook(...): ResponseEntity<Any> {
   val book = service.getBook(id)
   return Response.ok().body(book)
}

Service.kts

suspend fun getBook(id: String): Any? {
   return webClient.get()
   .uri("$baseUrl")
   .accept(MediaType.APPLICATION_JSON)
   .awaitExchange { response ->
      if(response.statusCode().is4xxClientError) {
         return@awaitExchange // here is where I want to return either a custom exception as well as the status code
      }
      if(response.statusCode().is5xxServerError) {
         return@awaitExchange // similar to above but with 500 status code
      }
      return@awaitExchange response.awaitBody() // otherwise just return the body object
    }
}

Been having hard time figuring this out and how to pass that up to the controller. This all works if I just want to return the body, but I'm wanting to add better exception handling. Also with new spring version awaitExchange() is deprecated and will need to use awaitExchange {} lambda fun instead. One last thing, in the lambda function, it says that "'return' is now allowed here" and wants me to change it to return@awaitExchange ...


Solution

  • I was able to use onStatus(HttpStatus::is4xxClientError) to propagate the error to the controller using: Mono.error(ResponseStatusException(HttpStatus.BAD_REQUEST)