Commit 59a899a4 authored by Dave Syer's avatar Dave Syer

Add @ResponseStatus handler to global exception handler

We might need to revisit this to allow more fine-grained
control by users, but it seems like a sensible default.
The BasicErrorController now uses both of the deafult strategies
(ResponseStatusExceptionResolver and DefaultHandlerExceptionResolver)
from Spring MVC to try and determine an appropriate response.

Fixes gh-839
parent e7484c66
......@@ -43,6 +43,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver;
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
/**
......@@ -65,6 +66,8 @@ public class BasicErrorController implements ErrorController {
private DefaultHandlerExceptionResolver resolver = new DefaultHandlerExceptionResolver();
private ResponseStatusExceptionResolver statuses = new ResponseStatusExceptionResolver();
@Value("${error.path:/error}")
private String errorPath;
......@@ -76,7 +79,9 @@ public class BasicErrorController implements ErrorController {
@ExceptionHandler(Exception.class)
public void handle(HttpServletRequest request, HttpServletResponse response,
Exception e) throws Exception {
this.resolver.resolveException(request, response, null, e);
if (this.statuses.resolveException(request, response, null, e) == null) {
this.resolver.resolveException(request, response, null, e);
}
if (response.getStatus() == HttpServletResponse.SC_OK) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
......
......@@ -36,6 +36,7 @@ import org.springframework.boot.autoconfigure.web.BasicErrorControllerIntegratio
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.test.annotation.DirtiesContext;
......@@ -47,6 +48,7 @@ import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.View;
......@@ -93,6 +95,16 @@ public class BasicErrorControllerIntegrationTests {
assertTrue("Wrong content: " + content, content.contains("Expected!"));
}
@Test
public void testErrorWithResponseStatus() throws Exception {
MvcResult result = this.mockMvc.perform(get("/bang"))
.andExpect(status().isNotFound()).andReturn();
MvcResult response = this.mockMvc.perform(new ErrorDispatcher(result, "/error"))
.andReturn();
String content = response.getResponse().getContentAsString();
assertTrue("Wrong content: " + content, content.contains("Expected!"));
}
@Test
public void testBindingExceptionForMachineClient() throws Exception {
// In a real container the response is carried over into the error dispatcher, but
......@@ -151,6 +163,11 @@ public class BasicErrorControllerIntegrationTests {
throw new IllegalStateException("Expected!");
}
@RequestMapping("/bang")
public String bang() {
throw new NotFoundException("Expected!");
}
@RequestMapping("/bind")
public String bind() throws Exception {
BindException error = new BindException(this, "test");
......@@ -162,6 +179,15 @@ public class BasicErrorControllerIntegrationTests {
}
@ResponseStatus(value = HttpStatus.NOT_FOUND)
private static class NotFoundException extends RuntimeException {
public NotFoundException(String string) {
super(string);
}
}
private class ErrorDispatcher implements RequestBuilder {
private MvcResult result;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment