Skip to content

WebMvc.fn: ServerResponse.async does not handle exceptions as expected #25931

@jonasbark

Description

@jonasbark

Affects:
v5.3.0-RC1

Related Kotlin Slack conversation:
https://kotlinlang.slack.com/archives/C0B8ZTWE4/p1602780417061400

When using functional routing and MVC the exception handling when using ServerResponse.async does not work as expected:

Router:

@Bean
    fun route(
        categoryHandler: TestHandler,
    ): RouterFunction<ServerResponse> = router {
        "/categories".nest {
           GET("/{categoryId}", categoryHandler::categoriesCategoryIdGet)
        }
    }

Implementation:

 fun categoriesCategoryIdGet(request: ServerRequest): ServerResponse {

         return ServerResponse.async(mono(Dispatchers.Unconfined) {
            throw ResponseStatusException(HttpStatus.BAD_GATEWAY)
        })
    }

I would expect the request to show HTTP Bad Gateway, but instead I'm getting HTTP 200 with an empty response:

 curl -v 'http://localhost:8080/categories/1/'
...
< HTTP/1.1 200
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Content-Length: 0
< Date: Mon, 19 Oct 2020 06:33:06 GMT
<
* Connection #0 to host localhost left intact
* Closing connection 0

with the following exception in the server:

javax.servlet.ServletException: javax.servlet.ServletException: org.springframework.web.server.ResponseStatusException: 502 BAD_GATEWAY
	at org.springframework.web.servlet.function.ErrorHandlingServerResponse.handleError(ErrorHandlingServerResponse.java:69) ~[spring-webmvc-5.3.0-RC2.jar:5.3.0-RC2]
	at org.springframework.web.servlet.function.AsyncServerResponse.lambda$writeTo$0(AsyncServerResponse.java:116) ~[spring-webmvc-5.3.0-RC2.jar:5.3.0-RC2]
	at java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:760) ~[na:1.8.0_201]
	at java.util.concurrent.CompletableFuture.uniWhenCompleteStage(CompletableFuture.java:778) ~[na:1.8.0_201]
	at java.util.concurrent.CompletableFuture.whenComplete(CompletableFuture.java:2140) ~[na:1.8.0_201]
	at org.springframework.web.servlet.function.AsyncServerResponse.writeTo(AsyncServerResponse.java:103) ~[spring-webmvc-5.3.0-RC2.jar:5.3.0-RC2]
	at org.springframework.web.servlet.function.support.HandlerFunctionAdapter.handle(HandlerFunctionAdapter.java:77) ~[spring-webmvc-5.3.0-RC2.jar:5.3.0-RC2]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1061) ~[spring-webmvc-5.3.0-RC2.jar:5.3.0-RC2]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:961) ~[spring-webmvc-5.3.0-RC2.jar:5.3.0-RC2]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.0-RC2.jar:5.3.0-RC2]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.0-RC2.jar:5.3.0-RC2]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:626) ~[tomcat-embed-core-9.0.39.jar:4.0.FR]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.0-RC2.jar:5.3.0-RC2]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.39.jar:4.0.FR]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.39.jar:9.0.39]

I would expect the request to be handled by e.g. ResponseStatusExceptionHandler and the ModelAndView exception handler.
I did not find documentation about the async handling.

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