package io.hosuaby.restful.controllers; import io.hosuaby.restful.domain.validators.TeapotValidator; import io.hosuaby.restful.services.exceptions.teapots.TeapotAlreadyExistsException; import io.hosuaby.restful.services.exceptions.teapots.TeapotInternalErrorException; import io.hosuaby.restful.services.exceptions.teapots.TeapotNotConnectedException; import io.hosuaby.restful.services.exceptions.teapots.TeapotNotExistsException; import io.hosuaby.restful.services.exceptions.teapots.TeapotsAlreadyExistException; import io.hosuaby.restful.services.exceptions.teapots.TeapotsNotExistException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.ObjectError; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.ResponseStatus; /** * Exception handler for all controllers. */ @ControllerAdvice public class GlobalExceptionHandler { /** * Internal server error message. */ private static final String ERR_INTERNAL_SERVER_ERROR = "Internal server error"; /** * Teapot validator. */ @Autowired private TeapotValidator teapotValidator; /** * Adds {@link TeapotValidator} to WebDataBinder. * * @param binder WebDataBinder */ @InitBinder public void dataBinding(WebDataBinder binder) { binder.addValidators(teapotValidator); } /** * Handles {@link TeapotAlreadyExistsException}. * * @param exception exception * * @return response entity */ @ExceptionHandler(TeapotAlreadyExistsException.class) public ResponseEntity<String> handleTeapotAlreadyExistsException( TeapotAlreadyExistsException exception) { return new ResponseEntity<String>( exception.getMessage(), HttpStatus.CONFLICT); } /** * Handles {@link TeapotNotExistsException}. * * @param exception exception * * @return response entity */ @ExceptionHandler(TeapotNotExistsException.class) public ResponseEntity<String> handleTeapotNotExistsException( TeapotNotExistsException exception) { return new ResponseEntity<String>( exception.getMessage(), HttpStatus.NOT_FOUND); } /** * Handles {@link TeapotsAlreadyExistException}. * * @param exception exception * * @return response entity */ @ExceptionHandler(TeapotsAlreadyExistException.class) public ResponseEntity<String> handleTeapotsAlreadyExistException( TeapotsAlreadyExistException exception) { return new ResponseEntity<String>( exception.getMessage(), HttpStatus.CONFLICT); } /** * Handles {@link TeapotsNotExistException}. * * @param exception exception * * @return response entity */ @ExceptionHandler(TeapotsNotExistException.class) public ResponseEntity<String> handleTeapotsNotExistException( TeapotsNotExistException exception) { return new ResponseEntity<String>( exception.getMessage(), HttpStatus.NOT_FOUND); } /** * Handles {@link TeapotNotConnectedException}. * * @param exception exception * * @return response entity */ @ExceptionHandler(TeapotNotConnectedException.class) public ResponseEntity<String> handleTeapotNotConnectedException( TeapotNotConnectedException exception) { return new ResponseEntity<String>( exception.getMessage(), HttpStatus.NOT_FOUND); } /** * Handles validation errors. * * @param exception exception * * @return response entity */ @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<String> handleValidationExeption( MethodArgumentNotValidException exception) { StringBuilder sb = new StringBuilder("Validation errors:"); for (ObjectError error : exception.getBindingResult().getAllErrors()) { sb.append("\n\t- ").append(error.getDefaultMessage()); } return new ResponseEntity<String>( sb.toString(), HttpStatus.BAD_REQUEST); } /** * Handles internal teapot errors provoked by unsupported command. * * @param exception exception * * @return response entity */ @ExceptionHandler(TeapotInternalErrorException.class) public ResponseEntity<String> handleTeapotInternalErrorException( TeapotInternalErrorException exception) { return new ResponseEntity<String>( exception.getMessage(), HttpStatus.I_AM_A_TEAPOT); // I am a teapot! } /** * Default handler for unhandled exceptions. */ @ExceptionHandler(Exception.class) @ResponseStatus( code = HttpStatus.INTERNAL_SERVER_ERROR, reason = ERR_INTERNAL_SERVER_ERROR) public void handleOtherExceptions(Exception exception) { // TODO: replace by logger exception.printStackTrace(); } }