'Strange behaviour of the exception handler on spring boot RestControllerAdvice handleExceptionInternal
Trying to save 2 times the same barcode card the method saveBarcodecard (left side image) throw the error: SQLIntegrityConstraintViolationException: "Duplicate entry '1-*****-EAN13' for key 'fcs_barcodecards.UK4ComplexKey" that I was expected to be intercepted by the method: handleExceptionInternal meant to handler ALL the Exceptions that are not specifically custom implemented but not.
Please note that: SQLIntegrityConstraintViolationException extends ... extends ... Exception
I need to implement a custom handler handleSQLIntegrityConstraintViolationException (please see the image 2 below -green-) to solve this issue.
My simple question is: how come this? :)
Many thanks in advance for your answers, if any :)
@Service
public class FcsBarcodecardServiceImpl implements FcsBarcodecardService {
@Autowired
FcsBarcodecardRepository fcsBarcodecardRepository;
@Autowired
private FcsClientRepository fcsClientRepository;
@Autowired
private FcsBarcodecardMapper fcsBarcodecardMapper;
@Override
public FcsBarcodecardResponse saveBarcodecard(Long clientId, FcsBarcodecard fcsBarcodecard) {
Optional<FcsClient> fcsClient = fcsClientRepository.findById(clientId);
if (!fcsClient.isPresent()) {
throw new UsernameNotFoundException("This client do not exists!");
}
fcsBarcodecard.setFcsClient(fcsClient.get());
return fcsBarcodecardMapper
.fromFcsBarcodecardToFcsBarcodecardResponse(
fcsBarcodecardRepository.save(fcsBarcodecard));
}
}
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
private static final String VALIDATION_ERROR_CHECK_ERRORS_FIELD_FOR_DETAILS = "Validation error. Check 'errors' field for details.";
/**
* Predefined: A single place to customize the response body of all exception
* types.
*/
@Override
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseEntity<Object> handleExceptionInternal(Exception exception, Object body, HttpHeaders headers,
HttpStatus status, WebRequest request) {
return buildErrorResponse(exception, FCS_EALLTYPES500, status, request);
}
@ExceptionHandler(SQLIntegrityConstraintViolationException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseEntity<Object> handleSQLIntegrityConstraintViolationException(SQLIntegrityConstraintViolationException ex,
WebRequest request) {
return buildErrorResponse(ex, FCS_EALLTYPES500, HttpStatus.INTERNAL_SERVER_ERROR, request);
}
Solution 1:[1]
ResponseEntityExceptionHandler#handleExceptionInternal()
is a place to customize the response body of only those exception types that are handled by an @ExceptionHandler
defined in ResponseEntityExceptionHandler
. As of the latest Spring version those are
@ExceptionHandler({
HttpRequestMethodNotSupportedException.class,
HttpMediaTypeNotSupportedException.class,
HttpMediaTypeNotAcceptableException.class,
MissingPathVariableException.class,
MissingServletRequestParameterException.class,
ServletRequestBindingException.class,
ConversionNotSupportedException.class,
TypeMismatchException.class,
HttpMessageNotReadableException.class,
HttpMessageNotWritableException.class,
MethodArgumentNotValidException.class,
MissingServletRequestPartException.class,
BindException.class,
NoHandlerFoundException.class,
AsyncRequestTimeoutException.class
})
Obviously your SQLIntegrityConstraintViolationException
is not among them and requires a separate exception handler to be caught and processed by.
If you'd like to have a single place to handle any expection, you'd have to specifically define an exception handler with e.g. @ExceptionHandler(Exception.class)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | dekkard |