Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HttpHandlerConnector does not propagate errors once response is committed #24051

Closed
bclozel opened this issue Nov 21, 2019 · 1 comment
Closed
Assignees
Labels
in: test Issues in the test module in: web Issues in web modules (web, webmvc, webflux, websocket)
Milestone

Comments

@bclozel
Copy link
Member

bclozel commented Nov 21, 2019

Since gh-23936, the HttpHandlerConnector uses a non-blocking thread for handling requests, thanks to Mono.defer and Schedulers.parallel().

With this new arrangement, any error happening after the response is committed is completely ignored and dropped. The resulting Mono<ClientHttpResponse> returned by the connector never completes and hangs.

Here is a test reproducing this issue:

@Test
public void handlerThrowingException() {
  TestHttpHandler handler = new TestHttpHandler(response ->
      response.setComplete()
          .then(Mono.error(new IllegalStateException("error while writing response body"))));

  Mono<ClientHttpResponse> connect = new HttpHandlerConnector(handler)
      .connect(HttpMethod.POST, URI.create("/path"), request -> request.writeWith(Mono.empty()));
  StepVerifier.create(connect)
      .expectError(IllegalStateException.class).verify();
}

This can happen if the server encounters an error while writing the response body (and the response has been completed already.

We've hit that problem in Spring Boot while upgrading Spring Framework, see spring-projects/spring-boot#19076.

I'm not sure how we're suppose to handle such errors and if WebTestClient should react. We might need to fix the test itself in Spring Boot, but I'd like to clarify that point first.

@bclozel bclozel added in: web Issues in web modules (web, webmvc, webflux, websocket) status: waiting-for-triage An issue we've not yet triaged or decided on labels Nov 21, 2019
@rstoyanchev rstoyanchev added in: test Issues in the test module and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Nov 21, 2019
@rstoyanchev rstoyanchev added this to the 5.2.2 milestone Nov 21, 2019
@rstoyanchev rstoyanchev self-assigned this Nov 21, 2019
@rstoyanchev
Copy link
Contributor

rstoyanchev commented Nov 21, 2019

The MonoProcessor<ClientHttpResponse> in HttpHandlerConnector which is used to pass the return value down the chain can be set 1) when the response is completed, or 2) when handling completes or errors. In this scenario both 1) and 2) are taking place.

After the change in #23936 to use a non-blocking thread, this is all now wrapped with Mono#defer and put on a thread marked "non-blocking". That seems to be causing the connect to never complete, and there is also this "Operator called default onErrorDropped" in the logs.

I suspect there may be a Reactor bug for the hanging part. That said we are responsible for trying to set a MonoProcessor twice which should not be taking place. We have to decide which result we want to complete the test with -- the completed response or the error that happened after it was completed?

I can see arguments for both sides. The simplest thing for a "mock" server to do is to assume the completed response is the final thing, since a real server may or may not have actually committed the response yet, and we would just log the error that is effectively dropped.

On the other hand it's easy to miss such an error in the logs arguably it might be more useful for a test to allow them to be "seen" and handled. This would also preserve current behavior.

bclozel added a commit to spring-projects/spring-boot that referenced this issue Nov 22, 2019
This commit updates the `responseCommitted` after changes were made in
`WebTestClient` with spring-projects/spring-framework#24051.

Fixes gh-19083
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: test Issues in the test module in: web Issues in web modules (web, webmvc, webflux, websocket)
Projects
None yet
Development

No branches or pull requests

2 participants