Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,9 @@ protected boolean shouldApplyTo(HttpServletRequest request, @Nullable Object han
}
catch (Throwable invocationEx) {
if (disconnectedClientHelper.checkAndLogClientDisconnectedException(invocationEx)) {
if (!response.isCommitted()) {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
return new ModelAndView();
}
// Any other than the original exception (or a cause) is unintended here,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,8 @@ protected ModelAndView handleAsyncRequestNotUsableException(AsyncRequestNotUsabl
* typically an {@link IOException} of a specific subtype or with a message
* specific to the underlying Servlet container. Those are detected through
* {@link DisconnectedClientHelper#isClientDisconnectedException(Throwable)}
* <p>By default, do nothing since the response is not usable.
* <p>By default, set the response status to 500 but otherwise do nothing
* since the response may not be usable.
* @param ex the {@code Exception} to be handled
* @param request current HTTP request
* @param response current HTTP response
Expand All @@ -522,6 +523,9 @@ protected ModelAndView handleAsyncRequestNotUsableException(AsyncRequestNotUsabl
protected ModelAndView handleDisconnectedClientException(
Exception ex, HttpServletRequest request, HttpServletResponse response, @Nullable Object handler) {

if (!response.isCommitted()) {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
return new ModelAndView();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,18 @@ void resolveExceptionAsyncRequestNotUsable() throws Exception {
assertThat(mav.isEmpty()).isTrue();
}

@Test
void resolveExceptionHandlerRethrowsDisconnectedClientException() throws Exception {
IOException ex = new IOException("Broken pipe");
HandlerMethod handlerMethod = new HandlerMethod(new RethrowingExceptionController(), "handle");
this.resolver.afterPropertiesSet();
ModelAndView mav = this.resolver.resolveException(this.request, this.response, handlerMethod, ex);

assertThat(mav).isNotNull();
assertThat(mav.isEmpty()).isTrue();
assertThat(this.response.getStatus()).isEqualTo(500);
}

@Test
void resolveExceptionJsonMediaType() throws UnsupportedEncodingException, NoSuchMethodException {
IllegalArgumentException ex = new IllegalArgumentException();
Expand Down Expand Up @@ -550,6 +562,18 @@ public void handleException() {
}


@Controller
static class RethrowingExceptionController {

public void handle() {}

@ExceptionHandler(IOException.class)
public void handleException(IOException ex) throws IOException {
throw ex;
}
}


@Controller
static class ModelArgumentController {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package org.springframework.web.servlet.mvc.support;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections;
Expand Down Expand Up @@ -171,6 +172,15 @@ void handleHttpMessageNotWritable() {
assertThat(response.getStatus()).as("Invalid status code").isEqualTo(500);
}

@Test
void handleDisconnectedClientException() {
Exception ex = new IOException("Broken pipe");
ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex);
assertThat(mav).as("No ModelAndView returned").isNotNull();
assertThat(mav.isEmpty()).as("No Empty ModelAndView returned").isTrue();
assertThat(response.getStatus()).as("Invalid status code").isEqualTo(500);
}

@Test
void handleMethodArgumentNotValid() throws Exception {
BeanPropertyBindingResult errors = new BeanPropertyBindingResult(new TestBean(), "testBean");
Expand Down