Skip to content

Commit

Permalink
Task 27 : Define GlobalExceptionHandler in userservice
Browse files Browse the repository at this point in the history
  • Loading branch information
Rapter1990 committed Jul 16, 2024
1 parent 1313a33 commit 3e1b603
Showing 1 changed file with 194 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
package com.springbootmicroservices.userservice.exception.handler;

import com.springbootmicroservices.userservice.exception.*;
import com.springbootmicroservices.userservice.model.common.CustomError;
import jakarta.validation.ConstraintViolationException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.ArrayList;
import java.util.List;

/**
* Global exception handler named {@link GlobalExceptionHandler} for handling various types of exceptions in the application.
*/
@RestControllerAdvice
public class GlobalExceptionHandler {

/**
* Handles MethodArgumentNotValidException thrown when validation on an argument annotated with @Valid fails.
*
* @param ex The MethodArgumentNotValidException instance.
* @return ResponseEntity with CustomError containing details of validation errors.
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
protected ResponseEntity<Object> handleMethodArgumentNotValid(final MethodArgumentNotValidException ex) {

List<CustomError.CustomSubError> subErrors = new ArrayList<>();

ex.getBindingResult().getAllErrors().forEach(
error -> {
String fieldName = ((FieldError) error).getField();
String message = error.getDefaultMessage();
subErrors.add(
CustomError.CustomSubError.builder()
.field(fieldName)
.message(message)
.build()
);
}
);

CustomError customError = CustomError.builder()
.httpStatus(HttpStatus.BAD_REQUEST)
.header(CustomError.Header.VALIDATION_ERROR.getName())
.message("Validation failed")
.subErrors(subErrors)
.build();

return new ResponseEntity<>(customError, HttpStatus.BAD_REQUEST);

}

/**
* Handles ConstraintViolationException thrown when a bean validation constraint is violated.
*
* @param constraintViolationException The ConstraintViolationException instance.
* @return ResponseEntity with CustomError containing details of constraint violations.
*/
@ExceptionHandler(ConstraintViolationException.class)
protected ResponseEntity<Object> handlePathVariableErrors(final ConstraintViolationException constraintViolationException) {

List<CustomError.CustomSubError> subErrors = new ArrayList<>();
constraintViolationException.getConstraintViolations()
.forEach(constraintViolation ->
subErrors.add(
CustomError.CustomSubError.builder()
.message(constraintViolation.getMessage())
.field(StringUtils.substringAfterLast(constraintViolation.getPropertyPath().toString(), "."))
.value(constraintViolation.getInvalidValue() != null ? constraintViolation.getInvalidValue().toString() : null)
.type(constraintViolation.getInvalidValue().getClass().getSimpleName())
.build()
)
);

CustomError customError = CustomError.builder()
.httpStatus(HttpStatus.BAD_REQUEST)
.header(CustomError.Header.VALIDATION_ERROR.getName())
.message("Constraint violation")
.subErrors(subErrors)
.build();

return new ResponseEntity<>(customError, HttpStatus.BAD_REQUEST);

}

/**
* Handles RuntimeException thrown for general runtime exceptions.
*
* @param runtimeException The RuntimeException instance.
* @return ResponseEntity with CustomError containing details of the runtime exception.
*/
@ExceptionHandler(RuntimeException.class)
protected ResponseEntity<?> handleRuntimeException(final RuntimeException runtimeException) {
CustomError customError = CustomError.builder()
.httpStatus(HttpStatus.NOT_FOUND)
.header(CustomError.Header.API_ERROR.getName())
.message(runtimeException.getMessage())
.build();

return new ResponseEntity<>(customError, HttpStatus.NOT_FOUND);
}

/**
* Handles PasswordNotValidException thrown when a password is not valid.
*
* @param ex The PasswordNotValidException instance.
* @return ResponseEntity with CustomError containing details of the exception.
*/
@ExceptionHandler(PasswordNotValidException.class)
protected ResponseEntity<Object> handlePasswordNotValidException(final PasswordNotValidException ex) {
CustomError customError = CustomError.builder()
.httpStatus(HttpStatus.BAD_REQUEST)
.header(CustomError.Header.API_ERROR.getName())
.message(ex.getMessage())
.build();

return new ResponseEntity<>(customError, HttpStatus.BAD_REQUEST);
}

/**
* Handles TokenAlreadyInvalidatedException thrown when a token is already invalidated.
*
* @param ex The TokenAlreadyInvalidatedException instance.
* @return ResponseEntity with CustomError containing details of the exception.
*/
@ExceptionHandler(TokenAlreadyInvalidatedException.class)
protected ResponseEntity<Object> handleTokenAlreadyInvalidatedException(final TokenAlreadyInvalidatedException ex) {
CustomError customError = CustomError.builder()
.httpStatus(HttpStatus.BAD_REQUEST)
.header(CustomError.Header.API_ERROR.getName())
.message(ex.getMessage())
.build();

return new ResponseEntity<>(customError, HttpStatus.BAD_REQUEST);
}

/**
* Handles UserAlreadyExistException thrown when a user already exists.
*
* @param ex The UserAlreadyExistException instance.
* @return ResponseEntity with CustomError containing details of the exception.
*/
@ExceptionHandler(UserAlreadyExistException.class)
protected ResponseEntity<Object> handleUserAlreadyExistException(final UserAlreadyExistException ex) {
CustomError customError = CustomError.builder()
.httpStatus(HttpStatus.CONFLICT)
.header(CustomError.Header.API_ERROR.getName())
.message(ex.getMessage())
.build();

return new ResponseEntity<>(customError, HttpStatus.CONFLICT);
}

/**
* Handles UserNotFoundException thrown when a user is not found.
*
* @param ex The UserNotFoundException instance.
* @return ResponseEntity with CustomError containing details of the exception.
*/
@ExceptionHandler(UserNotFoundException.class)
protected ResponseEntity<Object> handleUserNotFoundException(final UserNotFoundException ex) {
CustomError customError = CustomError.builder()
.httpStatus(HttpStatus.NOT_FOUND)
.header(CustomError.Header.API_ERROR.getName())
.message(ex.getMessage())
.build();

return new ResponseEntity<>(customError, HttpStatus.NOT_FOUND);
}

/**
* Handles UserStatusNotValidException thrown when a user status is not valid.
*
* @param ex The UserStatusNotValidException instance.
* @return ResponseEntity with CustomError containing details of the exception.
*/
@ExceptionHandler(UserStatusNotValidException.class)
protected ResponseEntity<Object> handleUserStatusNotValidException(final UserStatusNotValidException ex) {
CustomError customError = CustomError.builder()
.httpStatus(HttpStatus.BAD_REQUEST)
.header(CustomError.Header.API_ERROR.getName())
.message(ex.getMessage())
.build();

return new ResponseEntity<>(customError, HttpStatus.BAD_REQUEST);
}


}

0 comments on commit 3e1b603

Please sign in to comment.