Summary

After upgrading from spring boot 2.2.8 to 2.3.1 we had failing tests. If we throw a ResponseStatusException in a RestController in the corresponding test (using WebTestClient) the body is empty (no content). However if we test it using curl/postman etc. the body is not empty and contains the desired error message in the json field "message".

Steps to reproduce

  1. Checkout sample application (e.g git clone https://github.com/WtfJoke/springwebtestclientbug.git)
  2. Run SampleControllerTest ▢️ πŸ”΄
  3. (Optional) Check out branch spring228
  4. (Optional) Run SampleControllerTest ▢️ βœ”οΈ

Notes

The demo projects also contains a branch with the same code with spring boot 2.2.8 where the same tests passes (see CI). grafik

Comment From: wilkinsona

This is the expected default behaviour in Spring Boot 2.3. Please see the relevant section of the release notes for details.

Comment From: WtfJoke

@wilkinsona Thank you for your answer and linking me to the corresponding section of the release notes. πŸ‘

What I dont get, is why is the behaviour different from WebTestClient and a regular http client like curl (where the error body is delivered, even if server.error.include-message is not defined)?

E.g why is the body included in curl and not in webtestclient?

Comment From: wilkinsona

Sorry, I missed that part of the problem. We'll need to take a closer look.

Comment From: wilkinsona

The body is not empty when using WebTestClient. If I modify you test to the following:

    @Test
    fun exception() {
        webTestClient.get().uri("/exception")
                .exchange()
                .expectStatus().isBadRequest
                .expectBody()
                .isEmpty()
    }

It fails with the following output:

Expected empty body

> GET http://localhost:59273/exception
> WebTestClient-Request-Id: [1]

No content

< 400 BAD_REQUEST Bad Request
< Content-Type: [application/json]
< Transfer-Encoding: [chunked]
< Date: [Mon, 22 Jun 2020 12:41:20 GMT]
< Connection: [close]

{"timestamp":"2020-06-22T12:41:20.124+00:00","status":400,"error":"Bad Request","message":"","path":"/exception"}

java.lang.AssertionError: Expected empty body

As expected, the body is not empty but message is empty. If I then reinstate your original test and add server.error.include-message=always to application.properties, the test passes.

Comment From: WtfJoke

Thanks for your analysis, I mistakenly took No content for empty body. Sorry about that.

I already tested server.error.include-message=always before and it works as expected πŸ‘

Comment From: wilkinsona

Ah, I see. In the output above, No content is for the body of the request.

Comment From: lackovic

I already tested server.error.include-mesage=always before and it works as expected πŸ‘

I had the same error and adding that property did not fix it. It was only after some time that I realized that an s was missing from mesage.

So the actual property is the following:

server.error.include-message=always

and needs to be added to test/resources/application.properties.