Class XResponseEntityExceptionHandler
java.lang.Object
org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler
uk.ac.ebi.utils.opt.springweb.exceptions.XResponseEntityExceptionHandler
- All Implemented Interfaces:
org.springframework.beans.factory.Aware
,org.springframework.context.MessageSourceAware
public class XResponseEntityExceptionHandler
extends org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler
A better web exception handler.
This catches all exceptions happening while answering to a web requests (ie, in the controllers)
and return a proper HTTP status with a proper response body. Namely, the latter is
based on
createProblemDetail(Exception, HttpStatusCode, String, String, Object[], WebRequest)
,
which in turn, is based on RFC-9457.
TODO: I've tested it in dependents only.- Author:
- Marco Brandizi
- Date:
- 30 Aug 2024
-
Field Summary
Modifier and TypeFieldDescriptionMaps known exceptions to HTTP statuses.protected boolean
If true,createProblemDetail(Exception, HttpStatusCode, String, String, Object[], WebRequest)
adds a 'trace' field to the RFC-9457 output all the exceptions in this class produce.Fields inherited from class org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler
logger, PAGE_NOT_FOUND_LOG_CATEGORY, pageNotFoundLogger
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionprotected org.springframework.http.ProblemDetail
createProblemDetail
(Exception ex, org.springframework.http.HttpStatusCode status, String defaultDetail, String detailMessageCode, Object[] detailMessageArguments, org.springframework.web.context.request.WebRequest request) Tweaks the original output to return more significant values: - sets detail to themost significant message
from ex - sets title to the original detail (which isn't so detailed), discards the original title (since it has low information most of the times) - sets type to the FQN of ex - adds the 'trace' property with the exception's stack trace (TODO: make it optional) As in the superclass, this is used byhandleExceptionInternal(Exception, Object, HttpHeaders, HttpStatusCode, WebRequest)
.protected org.springframework.http.HttpStatusCode
Used withinhandleMappedException(Exception, WebRequest)
.protected org.springframework.http.ResponseEntity<Object>
handleExceptionInternal
(Exception ex, Object body, org.springframework.http.HttpHeaders headers, org.springframework.http.HttpStatusCode statusCode, org.springframework.web.context.request.WebRequest request) All exceptions are eventually routed here.org.springframework.http.ResponseEntity<Object>
handleMappedException
(Exception ex, org.springframework.web.context.request.WebRequest request) Our own catch-all wrapper This tries to see if the exception is associated to some HTTP status code, by usingfindExceptionMapping(Exception)
.Methods inherited from class org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler
createResponseEntity, getMessageSource, handleAsyncRequestTimeoutException, handleBindException, handleConversionNotSupported, handleErrorResponseException, handleException, handleHandlerMethodValidationException, handleHttpMediaTypeNotAcceptable, handleHttpMediaTypeNotSupported, handleHttpMessageNotReadable, handleHttpMessageNotWritable, handleHttpRequestMethodNotSupported, handleMaxUploadSizeExceededException, handleMethodArgumentNotValid, handleMethodValidationException, handleMissingPathVariable, handleMissingServletRequestParameter, handleMissingServletRequestPart, handleNoHandlerFoundException, handleNoResourceFoundException, handleServletRequestBindingException, handleTypeMismatch, setMessageSource
-
Field Details
-
exception2StatusCode
protected Map<Class<? extends Exception>,org.springframework.http.HttpStatusCode> exception2StatusCodeMaps known exceptions to HTTP statuses. This is scanned in the order you define the classes and that MUST be from the most specific one to the more generic. -
isStackTraceEnabled
protected boolean isStackTraceEnabledIf true,createProblemDetail(Exception, HttpStatusCode, String, String, Object[], WebRequest)
adds a 'trace' field to the RFC-9457 output all the exceptions in this class produce.
-
-
Constructor Details
-
XResponseEntityExceptionHandler
public XResponseEntityExceptionHandler()
-
-
Method Details
-
handleMappedException
@ExceptionHandler public org.springframework.http.ResponseEntity<Object> handleMappedException(Exception ex, org.springframework.web.context.request.WebRequest request) Our own catch-all wrapper This tries to see if the exception is associated to some HTTP status code, by usingfindExceptionMapping(Exception)
. It then invokeshandleExceptionInternal(Exception, Object, HttpHeaders, HttpStatusCode, WebRequest)
with the found status code (or null code). This bypassesResponseEntityExceptionHandler.handleException(Exception, WebRequest)
and all the defaults in the parent handler. We have tried the alternative route to call this method with aResponseStatusException
wrapper, but we don't want the latter to be returned to the client as top-level exception. Instead, we intercept occurred exceptions here and then we callhandleExceptionInternal(Exception, Object, HttpHeaders, HttpStatusCode, WebRequest)
. -
handleExceptionInternal
@Nullable protected org.springframework.http.ResponseEntity<Object> handleExceptionInternal(Exception ex, @Nullable Object body, org.springframework.http.HttpHeaders headers, org.springframework.http.HttpStatusCode statusCode, org.springframework.web.context.request.WebRequest request) All exceptions are eventually routed here.Does some tweaking of the default parent internal handler, before calling it as delegate:
- it always assign a status code, with 50x as fallback
- if body is null, it uses
createProblemDetail(Exception, HttpStatusCode, String, String, Object[], WebRequest)
with the reason taken from statusCode (original or 50x fallback)
- Overrides:
handleExceptionInternal
in classorg.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler
-
createProblemDetail
protected org.springframework.http.ProblemDetail createProblemDetail(Exception ex, org.springframework.http.HttpStatusCode status, String defaultDetail, @Nullable String detailMessageCode, @Nullable Object[] detailMessageArguments, org.springframework.web.context.request.WebRequest request) Tweaks the original output to return more significant values: - sets detail to themost significant message
from ex - sets title to the original detail (which isn't so detailed), discards the original title (since it has low information most of the times) - sets type to the FQN of ex - adds the 'trace' property with the exception's stack trace (TODO: make it optional) As in the superclass, this is used byhandleExceptionInternal(Exception, Object, HttpHeaders, HttpStatusCode, WebRequest)
.- Overrides:
createProblemDetail
in classorg.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler
-
findExceptionMapping
Used withinhandleMappedException(Exception, WebRequest)
. It tries to find one class in exception2StatusCode that is the same class of ex or a parent of it.- Returns:
- the corresponding status if it finds something, null otherwise.
-