Reputation: 12896
In my Spring Boot project I defined some @ExceptionHandler
classes in a @ControllerAdvice
to handle specific exceptions. These build an application-specific JSON reponse instead of the default provided by Spring Boot. So far this works fine for e.g. the MethodArgumentNotValidException
which is thrown in case the request validation fails.
@ExceptionHandler(value = {MethodArgumentNotValidException.class})
public ResponseEntity<ApplicationResponse> handleValidationException(MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getAllErrors().forEach((error) -> {
String fieldName = ((FieldError) error).getField();
String errorMessage = error.getDefaultMessage();
errors.put(fieldName, errorMessage);
});
log.error("Validation failed: {}", errors);
return buildErrorResponse(ApplicationError.REQUEST_BODY_VALIDATION_FAILED, errors.toString(), HttpStatus.BAD_REQUEST);
}
This approach seems reasonable to me for all exceptions I'm aware of. But what happens if an exception is thrown for which no @ExceptionHandler
exists? Then Spring Boot's default will kick in resulting in a JSON response which looks different from my custom one.
My first idea was to add an @ExceptionHandler
for the Exception
class like this:
@ExceptionHandler(value = {Exception.class})
public ResponseEntity<ApplicationResponse> handleValidationException(Exception ex) {
log.error("An unhandled error occurred: {}", ex.getMessage());
return buildErrorResponse(ApplicationError.GENERIC_ERROR, HttpStatus.INTERNAL_SERVER_ERROR);
}
While this seems to be working I wonder if this approach could have some major drawbacks I'm not aware of. How would you response with a custom JSON structure for any error that might occur?
Upvotes: 1
Views: 1376
Reputation:
Spring has several ways to deal with an exception handler as you can see here. Use @ControllerAdvice
with several @ExceptionHandler
has the following advantages:
Regarding to include a @ExceptionHandler(value = {Exception.class})
to manage exceptions without an specific handler, a better option is create the next one: @ExceptionHandler(Throwable.class)
, in that way you will be able to manage all potential problems in your application.
About return a Json when in your application an error happens, you can configure it in the response itself. For example:
private ResponseEntity<ErrorResponseDto> buildErrorResponse(RestApiErrorCode errorCode, List<String> errorMessages, HttpStatus httpStatus) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(APPLICATION_JSON);
ErrorResponseDto error = new ErrorResponseDto(errorCode, errorMessages);
return new ResponseEntity<>(error, headers, httpStatus);
}
You can see the rest of the code here
Upvotes: 1