Java выдает неправильное исключение

Я создал 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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
991
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Это происходит из-за того, что ваш блок 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.

благодаря обоим ответам. Я переместил свой пароль, если заявление о try/catch, сделал подтверждение пароля обязательным, и теперь все работает

reactFullStackDeveloper 07.06.2019 19:12

Советую разбить на разные методы и сделать модульным:

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.");
}

Другие вопросы по теме