Search code examples
javarestexceptionoverriding

How to simplify several methods with similar bodies into one?


I would like to simplify my code and merge common parts of the several methods into new one. Could you give me the piece of advice - what is the best way to do it? My methods are:

@ExceptionHandler(value = {ProhibitedScimTypeException.class})
public ResponseEntity<ErrorDto> policyConflict(final ProhibitedScimTypeException exception) {
    final var errorDto = new ErrorDto();
    errorDto.setDetail(exception.getMessage());
    errorDto.setStatus(BAD_REQUEST.toString());
    errorDto.setScimType("prohibited");
    return new ResponseEntity<>(errorDto, HttpStatus.BAD_REQUEST);
}

@ExceptionHandler(value = {UserAlreadyExistsException.class})
public ResponseEntity<ErrorDto> userNameExistsConflict(final UserAlreadyExistsException exception) {
    final var errorDto = new ErrorDto();
    errorDto.setDetail(exception.getMessage());
    errorDto.setStatus(CONFLICT.toString());
    errorDto.setScimType("uniqueness");
    return new ResponseEntity<>(errorDto, HttpStatus.CONFLICT);
}

@ExceptionHandler(value = {UserNotFoundException.class})
public ResponseEntity<ErrorDto> userNameNotFoundConflict(final UserNotFoundException exception) {
    final var errorDto = new ErrorDto();
    errorDto.setDetail(exception.getMessage());
    errorDto.setStatus(NOT_FOUND.toString());
    errorDto.setScimType("prohibited");
    return new ResponseEntity<>(errorDto, HttpStatus.NOT_FOUND);
}

I would like to separate the common part which is:

final var errorDto = new ErrorDto();
errorDto.setDetail(exception.getMessage());
errorDto.setStatus(MEHTOD.toString());
errorDto.setScimType("something");

Solution

  • can you extract the common part to a method like this?

    private ResponseEntity<ErrorDto> conflict(final Throwable exception, HttpStatus status, String scrimType) {
        final var errorDto = new ErrorDto();
        errorDto.setDetail(exception.getMessage());
        errorDto.setStatus(status.toString());
        errorDto.setScimType(scrimType);
        return new ResponseEntity<>(errorDto, status);
    }
    

    and call it from your methods,

    @ExceptionHandler(value = {ProhibitedScimTypeException.class})
    public ResponseEntity<ErrorDto> policyConflict(final ProhibitedScimTypeException exception) {
        return conflict(exception, HttpStatus.BAD_REQUEST, "prohibited");
    }
    
    @ExceptionHandler(value = {UserAlreadyExistsException.class})
    public ResponseEntity<ErrorDto> userNameExistsConflict(final UserAlreadyExistsException exception) {
        return conflict(exception, HttpStatus.CONFLICT, "uniqueness");
    }
    
    @ExceptionHandler(value = {UserNotFoundException.class})
    public ResponseEntity<ErrorDto> userNameNotFoundConflict(final UserNotFoundException exception) {
        return conflict(exception, HttpStatus.NOT_FOUND, "prohibited");
    }