3
votes

I work on a project with spring-boot (v2 M3) and spring-webflux. While coding a feature, I see that my microservice returns me an Http 200 status code while returning an error in a flux.

So, I make a simple test : I create a simple controller

@RestController
@RequestMapping(value = "/test")
public class TestController {

   @GetMapping(value = "/errors")
   public Flux<Object> getErrors() {
       return Flux.error(new RuntimeException("test"));
   }
}

With a simple exception handler :

@ControllerAdvice
public class TestExceptionHandler {

     private static final Logger LOGGER = LoggerFactory.getLogger(TestExceptionHandler.class);

     @ExceptionHandler(value = { RuntimeException.class })
     public ResponseEntity<String> handleServerError(final RuntimeException e) {
        LOGGER.error(e.getMessage(), e);
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
     }
}

And I test the result with the webTestClient in a integration test :

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource("classpath:test.properties")
public class TestErrorsIT {

    @Autowired
    private WebTestClient webTestClient;

    @Test
    public void getErrors() {

        this.webTestClient.get().uri("/test/errors").accept(MediaType.APPLICATION_STREAM_JSON).exchange().expectStatus()
                        .is5xxServerError();
    }
}

As a result, my test fails because my controller that returns an error flux returns a 200 status code instead of a 503 status code (the exception log "test" is well traced in my console). Do you know why ?

java.lang.AssertionError: Range for response status value 200 expected: but was:

GET http://localhost:54432/test/errors WebTestClient-Request-Id: [1] Accept: [application/stream+json]

No content

< 200 OK < Content-Type: [application/stream+json] < Transfer-Encoding: [chunked] < Date: [Fri, 03 Nov 2017 09:42:53 GMT]

Content not available yet

1
Could you create a sample project illustrating this issue? I've tried to reproduce this copying/pasting your code but can't reproduce it. - Brian Clozel
Hello Brian, thanks for your answer. I create a simple project and don't reproduce the issue. After more analysis today, I find that "spring-cloud-starter-eureka" that we use in our project has "spring-boot-starter-web" as dependency and provides "spring-webmvc". After exclusion of "spring-boot-starter-web", all works fine. Unfortunately, "spring-webmvc" is required for swagger (springfox) to work. So we have a working microservice but we lose swagger support... - Manuel KRUPA
Link for the springfox support of spring reactive : github.com/springfox/springfox/issues/1773 - Manuel KRUPA
You should definitely add that as an answer to your question. This will be useful to other SO members! - Brian Clozel

1 Answers

0
votes

In this instance, the application has a dependency on spring-cloud-starter-eureka, which itself has a transitive dependency on spring-boot-starter-web.

Adding spring-boot-starter-web to a Spring Boot application turns it into a Spring MVC application, which explains this behavior.