假设我们有一个方法changeUserName(Long id,String newName)
,它调用存储库的findUser(Long id)
来查找正确的用户实体,然后更改其名称。
当IllegalArgmentException
返回null时,是否适合播放findUser
?
或者我应该抛出自定义UserNotExistException
(扩展AppException扩展RuntimeException)?
的更新:
RuntimeException
:
@nachokk @JunedAhsan实际上我故意制作所有异常unchecked
,因为我认为这样可以使客户端代码干净,易于调试,更安全。至于那些“未处理的”,我将把它们全部捕捉到层的顶部,从而避免在UI上显示它们。
这是因为许多客户捕获checked exceptions
然后忽略它,在某些情况下他们不知道如何处理它。这是一个隐患。
澄清:
对不起,我的英语不好。我的意思是, changeUserName 应该抛出IllegalArgumentException
,而不是findUser
方法。还有一个问题:如何区分illegal argument
和business rule violation
?
答案 0 :(得分:2)
您应该使用UserNotExistException
。这个名字非常具体地说明了正在发生的事情。在我看来,你应该避免返回null
,但如果你这样做,你必须记录它。
<强>更新强>
我在想,正如@JunedAhsan所说,UserNotExistException
可能更好CheckedException
(从Exception扩展而不是RuntimeException)。
从此链接:Unchecked Exceptions : Controversy
如果可以合理地期望客户从异常中恢复, 使它成为检查异常。如果客户端无法做任何事情来恢复 从异常中,将其作为未经检查的例外。
/**
* @return User found or throw UserNotExistException if is not found
*/
public User findUser(Long id) throws UserNotExistException{
//some code
User user = giveMeUserForSomePlace();
if(user == null){
throw new UserNotExistException();
}
return user;
}
答案 1 :(得分:1)
这取决于你如何处理异常。
如果您只使用e.getMessage()显示错误报告,并且您不关心重复的字符串附加代码,则IllegalArgumentException是可以的。
我通过使用自定义例外找到了一些优势:
<强> 1。减少代码:
假设changeUserName肯定不是你加载User的唯一情况,所以每次调用repository.findUser(Long id)时都会发生下面的代码片段
if (user == null) {
throw new IllegalArgumentException("No such user found with given id["+ userId +"]");
}
另一方面,临时例外更方便:
if (user == null) {
throw new UserNotExistException(userId);
}
public class UserNotExistException extends RuntimeException {
public UserNotExistException(Long id) {
super("No such user found with given id["+ id +"]");
}
}
<强> 2。您需要更多的例外支持:
也许您需要返回状态代码或类似的东西。自定义异常层次结构可能会有所帮助:
请参阅this answer了解详细信息。
答案 2 :(得分:0)
我也建议使用UserNotExistException
,但区别在于它不是未经检查的异常(通过扩展RuntimeException
),请将其设为检查异常(扩展Exception
如果AppException
尚未执行此操作)。
这将确保changeUserName
的调用者处理UserNotExistException
异常并使代码有点健壮。