Skip to content

WebClient logs "Only one connection receive subscriber allowed" when response status is an error [SPR-17564] #22096

Closed
@spring-projects-issues

Description

@spring-projects-issues

Fethullah Misir opened SPR-17564 and commented

WebClient throws an IllegalStateException with:

Only one connection receive subscriber allowed

 when the server response status is 4xx / 5xx.

The issue is not reproducible with Spring Boot 2.1.0.RELEASE / WebFlux 5.1.2.RELEASE. 

 

I  reproduced the issue with the test below:

@Test
public void testRetrieveDoesThrowMultipleSubscriberError() {
   stubFor( get( urlEqualTo( "/notFound" ) )
         .willReturn( aResponse().withHeader( HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE )
                                 .withBody( "{}" )
                                 .withStatus( HttpStatus.NOT_FOUND_404 ) ) );

   StepVerifier.create( webClient.get()
                                 .uri( "/notFound" )
                                 .accept( MediaType.APPLICATION_JSON )
                                 .retrieve()

                                 .bodyToMono( String.class ) )
               .expectError( WebClientException.class )
               .verify();
}
 

The test pasess, however the below stack trace is logged: 

Caused by: java.lang.IllegalStateException: Only one connection receive subscriber allowed.
        ... 143 common frames omitted
        Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Assembly trace from producer [reactor.core.publisher.FluxMap] :
        reactor.core.publisher.Flux.map(Flux.java:5655)
        reactor.netty.ByteBufFlux.fromInbound(ByteBufFlux.java:70)
        reactor.netty.channel.ChannelOperations.receive(ChannelOperations.java:225)
        org.springframework.http.client.reactive.ReactorClientHttpResponse.getBody(ReactorClientHttpResponse.java:64)
        org.springframework.web.reactive.function.BodyExtractors.consumeAndCancel(BodyExtractors.java:268)
        org.springframework.web.reactive.function.BodyExtractors.lambda$skipBodyAsMono$21(BodyExtractors.java:264)
.....
.....
        io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:500)
        io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:462)
        io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:897)
Error has been observed by the following operator(s):
        |_      Flux.map ? reactor.netty.ByteBufFlux.fromInbound(ByteBufFlux.java:70)
        |_      Flux.doOnSubscribe ? org.springframework.http.client.reactive.ReactorClientHttpResponse.getBody(ReactorClientHttpResponse.java:65)
 

 

I attached a sample, to reproduce the issue.

It seams that the issue is related to the default status handler. When registering a custom one, the stacktrace is not logged and it works as expected.

StepVerifier.create( webClient.get()
                              .uri( "/notFound" )
                              .accept( MediaType.APPLICATION_JSON )
                              .retrieve()
                              .onStatus( status -> true, response -> Mono.error(IllegalStateException::new ) )
                              .bodyToMono( String.class ) )
            .expectError( IllegalStateException.class )
            .verify(); 

 

 

 

 


Affects: 5.1.3

Attachments:

Issue Links:

Referenced from: commits 7a5f8e0

Metadata

Metadata

Assignees

Labels

in: webIssues in web modules (web, webmvc, webflux, websocket)type: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions