Reputation: 1346
I want to define a common exception manger in my project, so I use @ControllerAdvice to do, the snippet of code is below:
@ExceptionHandler(Exception.class)
public ModelAndView handleAllException(HttpServletRequest request, Exception ex) throws Exception
{
LOGGER.error(ex.getMessage());
ModelAndView mav = new ModelAndView();
mav.addObject("exception", ex);
mav.addObject("url", request.getRequestURL());
mav.setViewName(ViewConstants.INTERNAL_ERROR_VIEW);
return mav;
}
it will return a common error page. That's great for normal exception of request. But if this is a Ajax request, the result is so ugly. so I add the code to judge it. The added code is below:
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
// return HTTP Status code and response message
} else {
// return error page name
}
I don't think it is the best way, anybody have a good opinion?
Upvotes: 5
Views: 3167
Reputation: 20966
...
public class Application extends SpringBootServletInitializer {
@Bean(name = "simpleMappingExceptionResolver")
public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver() {
SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver();
r.setDefaultErrorView("forward:/errorController");
return r;
}
@Controller
public class ErrorController {
public static final Logger LOG = Logger.getLogger(ErrorController.class);
@RequestMapping(value = "/errorController")
public ModelAndView handleError(HttpServletRequest request,
@RequestAttribute("exception") Throwable th) {
ModelAndView mv = null;
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
if (isBusinessException(th)) {
mv = new ModelAndView("appAjaxBadRequest");
mv.setStatus(BAD_REQUEST);
} else {
LOG.error("Internal server error while processing AJAX call.", th);
mv = new ModelAndView("appAjaxInternalServerError");
mv.setStatus(INTERNAL_SERVER_ERROR);
}
mv.addObject("message", getUserFriendlyErrorMessage(th).replaceAll("\r?\n", "<br/>"));
} else {
LOG.error("Cannot process http request.", th);
mv = new ModelAndView("appErrorPage");
mv.addObject("exeption", th);
}
return mv;
}
}
Upvotes: 0
Reputation: 628
I have all my controllers in different packages based on whether they serve AJAX requests or not. Then I can set #basePackages element on the ControllerAdvice annotations to handle the exception accordingly
Update: See RequestMapping#params and RequestMapping#headers to separate controllers based on headers and/or params
Upvotes: 1
Reputation: 934
If you use jQuery for making requests, you could use the following:
jQuery.ajaxSetup({
headers: { 'ajax-request': true },
statusCode: {
400: function (xhr) {
...do something
},
500: function (xhr) {
...do something
}
...
}
});
Upvotes: 0
Reputation: 1430
I would suggest to set error response code on any request, think this is a good practice to notify client that something goes wrong not depending on type of request. And for ajax request you can return same page and identify problem by error code.
Upvotes: 0