micronaut-core: Error Handling (`@Error`) for HttpClientResponseException does not provide response.body (body is null / empty)
Running on micronaut 1.2.6 and Kotlin 1.3.50.
Consider the following snippet:
@Client("\${formValidatorService.host}")
interface FormValidatorServiceClient {
@Post("/validate")
fun validate(@Body validationRequest: Single<FormSubmission>): Single<HttpResponse<ValidationResponseValid>>
}
@Controller("/forms")
open class FormSubmissionController(private val formValidatorServiceClient: FormValidatorServiceClient) : FormSubmissionOperations {
override fun validate(submission: Single<FormSubmission>): Single<HttpResponse<ValidationResponseValid>> {
return formValidatorServiceClient.validate(submission).map {
HttpResponse.ok(it.body()!!)
}
}
@Error
fun formSubmissionException(request: HttpRequest<*>, exception: HttpClientResponseException): Single<HttpResponse<JsonError>> {
println(exception.response.body())
return Single.just(
HttpResponse.status<JsonError>(HttpStatus.BAD_REQUEST, "Form Validation Failure")
.body(JsonError(exception.response.body().toString()))
)
}
}
@Validated
interface FormSubmissionOperations {
@Post(value = "/validate", consumes = [MediaType.APPLICATION_JSON], produces = [MediaType.APPLICATION_JSON])
fun validate(@Body submission: Single<FormSubmission>): Single<HttpResponse<ValidationResponseValid>>
}
When /validate is run the @Error
is triggered by a 400 response returned by the @Client
, but the body is always null.
Using TRACE on the HTTP Client, I can confirm that valid JSON is being returned in the response of the HTTP Client’s request.
Also using response.getBody(BodyType)
, returns Optional.empty
Issue seems very similar to https://github.com/micronaut-projects/micronaut-core/issues/416
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 24 (12 by maintainers)
If some poor soul is still trying to figure out what to do in this one, the way it worked for me was:
Stream
handle the exception in the stream and make sure to parse the body (with the error) don’t throw or rethrow the exception that’s is set to happen .doOnError(throwable -> {
Error handler
create an handler for that error
If you remove the doOnError() cycle the body value will be dumped, try out by yourself
Hope it helps.
I was able to get response in reactive mode with below example
That is one way to go about it, however only really necessary for blocking operations. If you are processing the exception in the error handler of a reactive response, the body is available to be converted directly.
exception.response.getBody(SomeType)
. The reason it isn’t available to do so in blocking operations is because the body must be released and we wouldn’t have any idea when that should be done if the client is no longer part of the flow.