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
			
			
This commit is contained in:
		
							parent
							
								
									a90e4b230f
								
							
						
					
					
						commit
						95abd18fea
					
				| 
						 | 
				
			
			@ -142,7 +142,7 @@ public class DispatcherHandler implements WebHandler, ApplicationContextAware {
 | 
			
		|||
	private Mono<Void> handleResult(ServerWebExchange exchange, HandlerResult result) {
 | 
			
		||||
		return getResultHandler(result).handleResult(exchange, result)
 | 
			
		||||
				.otherwise(ex -> result.applyExceptionHandler(ex).then(exceptionResult ->
 | 
			
		||||
						getResultHandler(result).handleResult(exchange, exceptionResult)));
 | 
			
		||||
						getResultHandler(exceptionResult).handleResult(exchange, exceptionResult)));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private HandlerResultHandler getResultHandler(HandlerResult handlerResult) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,6 +25,7 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
 | 
			
		|||
import org.springframework.context.annotation.ComponentScan;
 | 
			
		||||
import org.springframework.context.annotation.Configuration;
 | 
			
		||||
import org.springframework.http.HttpHeaders;
 | 
			
		||||
import org.springframework.http.ResponseEntity;
 | 
			
		||||
import org.springframework.web.bind.annotation.ExceptionHandler;
 | 
			
		||||
import org.springframework.web.bind.annotation.GetMapping;
 | 
			
		||||
import org.springframework.web.bind.annotation.RestController;
 | 
			
		||||
| 
						 | 
				
			
			@ -52,13 +53,13 @@ public class RequestMappingExceptionHandlingIntegrationTests extends AbstractReq
 | 
			
		|||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void controllerThrowingException() throws Exception {
 | 
			
		||||
		String expected = "Recovered from error: Boo";
 | 
			
		||||
		String expected = "Recovered from error: State";
 | 
			
		||||
		assertEquals(expected, performGet("/thrown-exception", new HttpHeaders(), String.class).getBody());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void controllerReturnsMonoError() throws Exception {
 | 
			
		||||
		String expected = "Recovered from error: Boo";
 | 
			
		||||
		String expected = "Recovered from error: Argument";
 | 
			
		||||
		assertEquals(expected, performGet("/mono-error", new HttpHeaders(), String.class).getBody());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -78,19 +79,24 @@ public class RequestMappingExceptionHandlingIntegrationTests extends AbstractReq
 | 
			
		|||
 | 
			
		||||
		@GetMapping("/thrown-exception")
 | 
			
		||||
		public Publisher<String> handleAndThrowException() {
 | 
			
		||||
			throw new IllegalStateException("Boo");
 | 
			
		||||
			throw new IllegalStateException("State");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@GetMapping("/mono-error")
 | 
			
		||||
		public Publisher<String> handleWithError() {
 | 
			
		||||
			return Mono.error(new IllegalStateException("Boo"));
 | 
			
		||||
			return Mono.error(new IllegalArgumentException("Argument"));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@ExceptionHandler
 | 
			
		||||
		public Publisher<String> handleException(IllegalStateException ex) {
 | 
			
		||||
		public Publisher<String> handleArgumentException(IllegalArgumentException ex) {
 | 
			
		||||
			return Mono.just("Recovered from error: " + ex.getMessage());
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@ExceptionHandler
 | 
			
		||||
		public ResponseEntity<Publisher<String>> handleStateException(IllegalStateException ex) {
 | 
			
		||||
			return ResponseEntity.ok(Mono.just("Recovered from error: " + ex.getMessage()));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue