【问题标题】:Java throwing wrong exceptionJava抛出错误的异常
【发布时间】:2019-06-07 16:53:17
【问题描述】:

我创建了 2 个自定义异常来处理创建新用户并将其持久保存到数据库。电子邮件(用户名)是唯一 ID,因此如果电子邮件重复,则应引发异常,因为唯一 ID 已经存在。 我也在做一个密码确认匹配。此确认匹配也会引发密码不匹配的自定义异常。这两部分相互独立地正常工作,但是,当我将所有内容放在一起并进行测试时,如果密码确认失败,它会抛出用户名已经存在异常而不是密码不匹配异常。为什么?

我已经尝试重新排序代码,但这似乎并不重要。我也试过 if/else 而不是 just 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

【问题讨论】:

    标签: java spring-boot exception


    【解决方案1】:

    发生这种情况是因为您的 try {} catch (Exception e) {} 块正在捕获您在块内抛出的异常,在 try 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 抛出的异常并重新抛出它,然后它只会捕获该异常而不是全部)

    【讨论】:

      【解决方案2】:

      发生这种情况是因为您的 PasswordMatchException 扩展了 Exception 并且您的 catch 块正在捕获它并抛出 UsernameAlreadyExistsException

      减少你的代码来说明我的观点:

      try {
           throw new PasswordMatchException();
      } catch(Exception e) {
           throw new UsernameAlreadyExistsException();
      }
      

      如果不了解您的代码会抛出哪些类型的异常,您可能有两种解决方案:

      1) 捕获比Exception 更具体的内容。

      2) 将密码检查移到 try/catch 块之外。

      【讨论】:

      • 感谢这两个答案。我移动了有关 try/catch 的 if 语句的密码,要求确认密码,现在一切正常
      【解决方案3】:

      建议分解成不同的方法并使其模块化:

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

      【讨论】:

        猜你喜欢
        • 2017-10-07
        • 1970-01-01
        • 1970-01-01
        • 2012-07-23
        • 2012-05-24
        • 2012-08-26
        • 1970-01-01
        • 1970-01-01
        • 2011-02-07
        相关资源
        最近更新 更多