Search code examples
springspring-mvcexceptiondao

Throwing custom exceptions in multi-layered spring project


I am trying to handle the use case where there's a violation for an unique field (for example, the username/mail), would it be correct to handle it like so? (I am using jdbcInsert on the dao layer)

@Transactional
@Override
public User register(String name, String surname, String username, String email, String password) {
    User user = null;
    try {
        user = userDao.register(name, surname, username,
                email, passwordEncoder.encode(password));
    } catch (DuplicateKeyException duplicateKeyException) {
        throw new DuplicateUserException(duplicateKeyException.getMessage());
    } catch (DataAccessException dataAccessException) {
        throw new SystemUnavailableException(dataAccessException.getMessage());
    }
    return user;
}

And catching my custom exceptions in the controller:

@ControllerAdvice
public class ErrorControllerAdvice {
    @ExceptionHandler(DuplicateUserException.class)
    public ModelAndView keyViolation(DuplicateUserException ex) {
        ModelAndView mav = new ModelAndView("admin/user/new");
        mav.addObject("duplicateMessage", ex.getErrorMessage());
        return mav;
    }

    @ExceptionHandler(SystemUnavailableException.class)
    @ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
    public ModelAndView unexpectedDatabaseError(SystemUnavailableException ex) {
        LOGGER.error(ex.getErrorMessage());
        return new ModelAndView("500");
    }
}

Solution

  • Looks fine to me. Your custom exceptions live at a different level of abstraction, which gives them good reason for existing.

    You might consider handling the exceptions in your controller, instead of using an Error translator class (ErrorControllerAdvice) though. This makes things more explicit and limit surprises about how exceptions are handled.