Reputation: 1276
In Spring boot and rest application, i have configured a exception handler as following. It works fine if an exception is thrown after request makes it to rest service.
The Rest api expects Content-Type of "application/json" and If I do not send that content-type header to the api, exception handler does not catch the exception. It prints following information in the log:
DEBUG [o.s.w.s.DispatcherServlet] DispatcherServlet with name 'dispatcherServlet' processing PUT request for [/app/v1.0/customers/customer/zones/zoneName.]
DEBUG [o.s.w.s.m.m.a.RequestMappingHandlerMapping] Looking up handler method for path /app/v1.0/customers/customer/zones/zoneName.
DEBUG [o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver] Resolving exception from handler [null]: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'text/plain' not supported
DEBUG [o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver] Invoking @ExceptionHandler method: public final org.springframework.http.ResponseEntity<java.lang.Object> org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler.handleException(java.lang.Exception,org.springframework.web.context.request.WebRequest)
DEBUG [o.s.w.s.DispatcherServlet] Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
DEBUG [o.s.w.s.DispatcherServlet] Successfully completed request
Here's the exception handler class:
@ControllerAdvice
@RestController
public class ServiceExceptionHandler extends ResponseEntityExceptionHandler
{
@ExceptionHandler(Exception.class)
public final ResponseEntity<java.lang.Object> handleException(Throwable ex,WebRequest req)
{
ErrorResponse errorResponse = null;
if (ex instanceof ApiException)
{
errorResponse = new ErrorResponse((ApiException) ex);
}
else
{
logger.error(ex);
errorResponse = new ErrorResponse();
errorResponse.setCode(HttpCodes.HTTP_CODE_500);
errorResponse.setError(ex.getMessage());
}
return new ResponseEntity<Object>(errorResponse,
HttpStatus.valueOf(errorResponse.getCode()));
}
protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex,
HttpHeaders headers, HttpStatus status, WebRequest request)
{
Map<String, String> responseBody = new HashMap<String, String>();
responseBody.put("path", request.getContextPath());
responseBody.put("message",
"The URL you have reached is not in service at this time (404).");
return new ResponseEntity<Object>(responseBody, HttpStatus.NOT_FOUND);
}
}
Upvotes: 3
Views: 13577
Reputation: 1276
Here's final solution:
@ControllerAdvice
public class SpringExceptionHandler extends ExceptionHandlerExceptionResolver
{
@ExceptionHandler(org.springframework.web.HttpMediaTypeNotSupportedException.class)
public ResponseEntity<Object> handleControllerException(HttpMediaTypeNotSupportedException ex, WebRequest req)
{
ErrorResponse errorResponse = null;
ex.printStackTrace();
errorResponse = new ErrorResponse();
errorResponse.setCode(HttpCodes.HTTP_CODE_INTERNAL_ERROR);
errorResponse.setError(ex.getMessage());
return new ResponseEntity<Object>(errorResponse,
HttpStatus.valueOf(errorResponse.getCode()));
}
}
Now I need to make some changes to make it work for all exceptions including controller thrown but that is for later. (Thanks Adam).
Important note: if there's both a global handler and an entity handler, spring ignores global handler.
Upvotes: 2
Reputation: 2269
Your class will only catch errors raised from within a controller. The error you are seeing occurs before a controller is invoked, as Spring cannot find a controller to handle the request.
DEBUG [o.s.w.s.m.m.a.RequestMappingHandlerMapping] Looking up handler method for path /app/v1.0/customers/customer/zones/zoneName.
DEBUG [o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver] Resolving exception from handler [null]: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'text/plain' not supported
Notice the handler is null.
You will also need to implement a HandlerExceptionResolver
to handle that type of exception: http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/mvc.html#mvc-exceptionhandlers
See Spring exception handler outside controller for more details.
Upvotes: 5