Spring-framework: Clarify behavior for WebClient statusHandlers

Created on 6 Mar 2020  路  9Comments  路  Source: spring-projects/spring-framework

During Spring Boot 2.2 upgrade (from 2.1.x) we've noticed regression in tests using webclient.

Scenario: Call an enpoint returning 404 NOT_FOUND (with non-empty response body)

Expected: webclient returns empty Mono instance

spring-webflux >= 5.2.0
Actual: webclient call returns an non-empty response but the wrapped object has nothing more than nulls inside - unit test fails.

spring-webflux == 5.1.14
Actual: webclient call returns an empty response - unit test works fine.

Here is a sample that reproduces the problem: https://github.com/jmayday/emptymono
Please have a look at this unit test (it uses Wiremock) - _shouldReturnEmptyObjectFor404WithResponseBody_

Unit test result:

java.lang.AssertionError: 
Expecting an empty Optional but was containing value: <MyEntity(id=null, name=null, owner=null)>.

Pay attention, that if we'll modify response body in wiremock mapping and replace body

{"error_code":404,"message":"Page not found"}

with empty body, then test will work.

Is this a spring-webflux 5.2.x regression or I'm misusing it?

web documentation

All 9 comments

@jmayday thanks for the report but in order to understand what's going on we'll have to copy all that text in a project we can run from an IDE. Can you please edit your description without the text and a link to a github repo (or a zip we can download)?

@snicoll OK please give me 10 minutes

@jmayday thanks. I've edited your comment with the link to your sample to make the original description more readable.

Thanks for the sample. The test that is failing isn't making any use of Spring Boot. It's purely Spring Framework's WebClient communicating with a WireMock server. We'll transfer this to the Framework team so that they can take a look.

I believe this is due to https://github.com/spring-projects/spring-framework/commit/a9b3d95a14c316387f2b77328d6864b8e0a36721. As explained in the commit message (and Javadoc) an empty Mono effectively suppresses the error, and the bodyToMono tries to map the error JSON to the normal response Object, which results in null values.

I think the Javadoc could use some improvement. That aside, @poutsma what is your thought on the best way to achieve the effect of "no result", i.e. complete empty? Clearly that needs to be explained as well in the Javadoc as it is a valid case.

I think you'd have to use an ExchangeFilterFunction to accomplish this. The onStatus handlers are designed to map to an exception; not to an alternative (empty) result.

As said in the commit message, returning an empty result prior to a9b3d95 (eg 5.1.14) will actually leak memory (i.e. the body), so it never "worked" correctly in the first place.

@jmayday see the updated to the Javadoc in the referenced commit above. I've clarified the various cases and provides suggestions for your case.

Thank you.

Was this page helpful?
0 / 5 - 0 ratings