Я создал 2 пользовательских исключения для обработки создания и сохранения новых пользователей в БД. Электронная почта (имя пользователя) является уникальным идентификатором, поэтому, если электронная почта дублируется, должно быть выдано исключение, поскольку уникальный идентификатор уже существует. Я также делаю совпадение подтверждения пароля. Это совпадение с подтверждением также вызовет пользовательское исключение паролей, которые не совпадают. Эти две части работают правильно независимо друг от друга, однако, когда я собираю все вместе и проверяю, если подтверждение пароля не удается, выдается исключение имени пользователя, а не исключение паролей, не соответствующее исключению. Почему?
Я попытался изменить порядок кода, но это, похоже, не имеет значения. Я также пробовал if/else, а не просто if, но получил те же результаты
//Username(email) must be unique
try {
//password and confirm password must match
if (!newGcUser.getPassword().equals(newGcUser.getConfirmPassword())) {
throw new PasswordMatchException("password and confirm password does not match");
}
//if passwords match - persist to DB
newGcUser.setPassword(bCryptPasswordEncoder.encode(newGcUser.getPassword()));
//Do NOT persist or show the confirm Password
newGcUser.setConfirmPassword("");
//set user
newGcUser.setName(newGcUser.getUsername());
return userRepository.save(newGcUser);
} catch (Exception e) {
throw new UsernameAlreadyExistsException("Username: '" + newGcUser.getUsername() + "' already exists.");
}
}
Я использую Postman для тестирования. Если я проверяю электронную почту, которая, как я знаю, не зарегистрирована, и не соответствует паролям, я получаю сообщение UsernameAlreadyExistsException вместо PasswordMatchException




Это происходит из-за того, что ваш блок try {} catch (Exception e) {} перехватывает исключение, которое вы выбрасываете внутри блока, сгенерируйте исключение вне блока try catch, и оно должно сработать catch :
// password and confirm password must match
if (!newGcUser.getPassword().equals(newGcUser.getConfirmPassword())) {
throw new PasswordMatchException("password and confirm password does not match");
}
// Username(email) must be unique
try {
// if passwords match - persist to DB
newGcUser.setPassword(bCryptPasswordEncoder.encode(newGcUser.getPassword()));
// Do NOT persist or show the confirm Password
newGcUser.setConfirmPassword("");
// set user
newGcUser.setName(newGcUser.getUsername());
return userRepository.save(newGcUser);
} catch (Exception e) {
throw new UsernameAlreadyExistsException("Username: '" + newGcUser.getUsername() + "' already exists.");
}
(или поймайте менее общее исключение, например, исключение, которое выдается из userRepository.save, и повторно выдайте его, тогда оно будет перехватывать только это исключение, а не все)
Это происходит потому, что ваш PasswordMatchException расширяется Exception, а ваш блок захвата ловит его и бросает UsernameAlreadyExistsException.
Сокращение вашего кода, чтобы проиллюстрировать мою точку зрения:
try {
throw new PasswordMatchException();
} catch(Exception e) {
throw new UsernameAlreadyExistsException();
}
Не зная больше о том, какие типы исключений может вызывать ваш код, у вас, вероятно, есть два решения:
1) Поймай что-то более конкретное, чем Exception.
2) Переместите проверку пароля за пределы блока try/catch.
Советую разбить на разные методы и сделать модульным:
private void matchPassword(..newGcUser..) throws PasswordMatchException{
// password and confirm password must match
if (!newGcUser.getPassword().equals(newGcUser.getConfirmPassword())) {
throw new PasswordMatchException("password and confirm password does not match");
}
}
Метод сохранения должен перехватывать конкретное исключение:
// Username(email) must be unique
try {
// if passwords match - persist to DB
...
return userRepository.save(newGcUser);
} catch (DataIntegrityViolationException e) {
throw new UsernameAlreadyExistsException("Username: '" + newGcUser.getUsername() + "' already exists.");
}
благодаря обоим ответам. Я переместил свой пароль, если заявление о try/catch, сделал подтверждение пароля обязательным, и теперь все работает