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
This commit is contained in:
parent
e7484c66f5
commit
59a899a4da
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue