Skip to content

Commit 95abd18

Browse files
committed
Fix Exception Handling result handler resolution
Prior to this commit, the wrong `HandlerResultHandler` could be resolved when handling exceptions; this could happen only if the original handler and exception handler had different signatures: ``` Publisher<String> originalHandler() { ... } @ExceptionHandler(MyCustomException.class) ResponseEntity<Mono<String>> handleException() { ... } ``` In that case, the `ResponseBodyResultHandler` would be used when handling exceptions instead of the `ResponseEntityResultHandler`. This commit ensures that the `HandlerResult` returned by the exception handler is used to resolve the `HandlerResultHandler`. The latter will process the result and use it to write to the HTTP response. Issue: SPR-14876
1 parent a90e4b2 commit 95abd18

File tree

2 files changed

+12
-6
lines changed

2 files changed

+12
-6
lines changed

spring-web-reactive/src/main/java/org/springframework/web/reactive/DispatcherHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ private Mono<HandlerResult> invokeHandler(ServerWebExchange exchange, Object han
142142
private Mono<Void> handleResult(ServerWebExchange exchange, HandlerResult result) {
143143
return getResultHandler(result).handleResult(exchange, result)
144144
.otherwise(ex -> result.applyExceptionHandler(ex).then(exceptionResult ->
145-
getResultHandler(result).handleResult(exchange, exceptionResult)));
145+
getResultHandler(exceptionResult).handleResult(exchange, exceptionResult)));
146146
}
147147

148148
private HandlerResultHandler getResultHandler(HandlerResult handlerResult) {

spring-web-reactive/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingExceptionHandlingIntegrationTests.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.springframework.context.annotation.ComponentScan;
2626
import org.springframework.context.annotation.Configuration;
2727
import org.springframework.http.HttpHeaders;
28+
import org.springframework.http.ResponseEntity;
2829
import org.springframework.web.bind.annotation.ExceptionHandler;
2930
import org.springframework.web.bind.annotation.GetMapping;
3031
import org.springframework.web.bind.annotation.RestController;
@@ -52,13 +53,13 @@ protected ApplicationContext initApplicationContext() {
5253

5354
@Test
5455
public void controllerThrowingException() throws Exception {
55-
String expected = "Recovered from error: Boo";
56+
String expected = "Recovered from error: State";
5657
assertEquals(expected, performGet("/thrown-exception", new HttpHeaders(), String.class).getBody());
5758
}
5859

5960
@Test
6061
public void controllerReturnsMonoError() throws Exception {
61-
String expected = "Recovered from error: Boo";
62+
String expected = "Recovered from error: Argument";
6263
assertEquals(expected, performGet("/mono-error", new HttpHeaders(), String.class).getBody());
6364
}
6465

@@ -78,19 +79,24 @@ private static class TestController {
7879

7980
@GetMapping("/thrown-exception")
8081
public Publisher<String> handleAndThrowException() {
81-
throw new IllegalStateException("Boo");
82+
throw new IllegalStateException("State");
8283
}
8384

8485
@GetMapping("/mono-error")
8586
public Publisher<String> handleWithError() {
86-
return Mono.error(new IllegalStateException("Boo"));
87+
return Mono.error(new IllegalArgumentException("Argument"));
8788
}
8889

8990
@ExceptionHandler
90-
public Publisher<String> handleException(IllegalStateException ex) {
91+
public Publisher<String> handleArgumentException(IllegalArgumentException ex) {
9192
return Mono.just("Recovered from error: " + ex.getMessage());
9293
}
9394

95+
@ExceptionHandler
96+
public ResponseEntity<Publisher<String>> handleStateException(IllegalStateException ex) {
97+
return ResponseEntity.ok(Mono.just("Recovered from error: " + ex.getMessage()));
98+
}
99+
94100
}
95101

96102
}

0 commit comments

Comments
 (0)