Skip to content

Instantly share code, notes, and snippets.

@matsev
Last active January 16, 2023 06:04
Show Gist options
  • Save matsev/4519323 to your computer and use it in GitHub Desktop.
Save matsev/4519323 to your computer and use it in GitHub Desktop.
Generic response error handling using @ControllerAdvice
@ControllerAdvice
public class CustomResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
List<FieldError> fieldErrors = ex.getBindingResult().getFieldErrors();
List<ObjectError> globalErrors = ex.getBindingResult().getGlobalErrors();
List<String> errors = new ArrayList<>(fieldErrors.size() + globalErrors.size());
String error;
for (FieldError fieldError : fieldErrors) {
error = fieldError.getField() + ", " + fieldError.getDefaultMessage();
errors.add(error);
}
for (ObjectError objectError : globalErrors) {
error = objectError.getObjectName() + ", " + objectError.getDefaultMessage();
errors.add(error);
}
ErrorMessage errorMessage = new ErrorMessage(errors);
return new ResponseEntity(errorMessage, headers, status);
}
@Override
protected ResponseEntity<Object> handleHttpMediaTypeNotSupported(HttpMediaTypeNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
String unsupported = "Unsupported content type: " + ex.getContentType();
String supported = "Supported content types: " + MediaType.toString(ex.getSupportedMediaTypes());
ErrorMessage errorMessage = new ErrorMessage(unsupported, supported);
return new ResponseEntity(errorMessage, headers, status);
}
@Override
protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
Throwable mostSpecificCause = ex.getMostSpecificCause();
ErrorMessage errorMessage;
if (mostSpecificCause != null) {
String exceptionName = mostSpecificCause.getClass().getName();
String message = mostSpecificCause.getMessage();
errorMessage = new ErrorMessage(exceptionName, message);
} else {
errorMessage = new ErrorMessage(ex.getMessage());
}
return new ResponseEntity(errorMessage, headers, status);
}
}
@XmlRootElement
public class ErrorMessage {
private List<String> errors;
public ErrorMessage() {
}
public ErrorMessage(List<String> errors) {
this.errors = errors;
}
public ErrorMessage(String error) {
this(Collections.singletonList(error));
}
public ErrorMessage(String ... errors) {
this(Arrays.asList(errors));
}
public List<String> getErrors() {
return errors;
}
public void setErrors(List<String> errors) {
this.errors = errors;
}
}
@ControllerAdvice
class GlobalControllerExceptionHandler {
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
ErrorMessage handleException(MethodArgumentNotValidException ex) {
List<FieldError> fieldErrors = ex.getBindingResult().getFieldErrors();
List<ObjectError> globalErrors = ex.getBindingResult().getGlobalErrors();
List<String> errors = new ArrayList<>(fieldErrors.size() + globalErrors.size());
String error;
for (FieldError fieldError : fieldErrors) {
error = fieldError.getField() + ", " + fieldError.getDefaultMessage();
errors.add(error);
}
for (ObjectError objectError : globalErrors) {
error = objectError.getObjectName() + ", " + objectError.getDefaultMessage();
errors.add(error);
}
return new ErrorMessage(errors);
}
@ExceptionHandler
@ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
@ResponseBody
ErrorMessage getErrorMessage(HttpMediaTypeNotSupportedException ex) {
String unsupported = "Unsupported content type: " + ex.getContentType();
String supported = "Supported content types: " + MediaType.toString(ex.getSupportedMediaTypes());
return new ErrorMessage(unsupported, supported);
}
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
ErrorMessage getErrorMessage(HttpMessageNotReadableException ex) {
Throwable mostSpecificCause = ex.getMostSpecificCause();
if (mostSpecificCause != null) {
String exceptionName = mostSpecificCause.getClass().getName();
String message = mostSpecificCause.getMessage();
return new ErrorMessage(exceptionName, message);
}
return new ErrorMessage(ex.getMessage());
}
}
@ControllerAdvice
class GlobalControllerExceptionHandler {
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
ErrorMessage handleException(SomeException ex) {
ErrorMessage errorMessage = createErrorMessage(ex);
return errorMessage;
}
@ExceptionHandler
@ResponseStatus(HttpStatus.GONE)
@ResponseBody
ErrorMessage handleException(OtherException ex) {
ErrorMessage errorMessage = createErrorMessage(ex);
return errorMessage;
}
}
{
"errors": [
"name, may not be empty",
"email, not a well-formed email address"
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment