如何用带自定义消息的try{}catch{}块重构getUser方法并解决问题?
问题分析与解决方案
你的代码存在的核心问题
UserNotFoundException不会被触发:userRepository.findById()返回的是Optional,当找不到用户时只会返回空Optional,并不会主动抛出UserNotFoundException,所以你的catch块永远不会执行。- 方法路径不完整:
catch块中既没有返回值,也没有重新抛出异常,编译器要求方法的所有执行分支必须有返回值或抛出异常,因此提示缺少return语句。 - 冗余数据库查询:原代码中两次调用
findById(),会发起两次数据库请求,完全没必要。
修正后的代码实现(两种方案)
方案一:用Optional API简化逻辑(推荐)
利用Optional的orElseThrow()方法替代手动判断,同时用try-catch处理ID格式错误的情况:
public Optional<UserDTO> getUser(String id) { try { Integer userId = Integer.valueOf(id); // 一次查询,为空时主动抛出异常 return userRepository.findById(userId) .map(this::map) .orElseThrow(() -> new UserNotFoundException("User wasn't found")); } catch (NumberFormatException e) { // 处理ID格式非法的情况,可根据业务需求抛自定义异常或返回空 throw new InvalidUserIdException("Invalid user ID format"); } }
方案二:严格使用try-catch块(满足你的需求)
主动抛出UserNotFoundException后捕获处理,同时保证方法路径完整:
public Optional<UserDTO> getUser(String id) { try { Integer userId = Integer.valueOf(id); Optional<User> userOpt = userRepository.findById(userId); if (userOpt.isEmpty()) { // 主动抛出异常,让catch块捕获 throw new UserNotFoundException("User wasn't found"); } return userOpt.map(this::map); } catch (NumberFormatException e) { throw new InvalidUserIdException("Invalid user ID format"); } catch (UserNotFoundException e) { // 可在此处添加日志逻辑,然后重新抛出异常 System.out.println(e.getMessage()); throw e; } }
关键注意点
- 必须避免重复调用
findById(),减少不必要的数据库交互; findById()不会自动抛出用户不存在的异常,需要通过orElseThrow()或手动判断后主动抛出;catch块内要么返回符合方法返回值类型的结果,要么重新抛出异常,确保方法所有执行路径都有明确结果。
内容的提问来源于stack exchange,提问作者RobbLBobbl
相关产品推荐
相关产品推荐

