【问题标题】:Best way to return error description to user向用户返回错误描述的最佳方式
【发布时间】:2018-02-13 20:29:47
【问题描述】:

假设我需要在我的系统中注册用户。

商业规则是:

  • 电子邮件应该是唯一的(一种身份);
  • 名称不能为空。

看来我需要服务。

大概是这样的:

public interface RegistrationService {
  bool Register(String email, String name);
}

在我必须向用户返回失败原因之前,这很好。 如何处理?

我可以看到几个选项(但我不喜欢其中任何一个):

  1. 实现一种结果对象:

    公共接口注册服务{ RegistrationResult Register(String email, String name); } 公共接口注册服务{ 布尔成功(); 错误[] 错误(); 用户新用户(); }

这很好,甚至可能对 REST api 有用。 但是是不是太麻烦了(特别是考虑到可能应该在工厂检查空白名称)?

  1. 抛出异常

    公共接口注册服务{ 无效注册(字符串电子邮件,字符串名称)抛出注册错误; }

它看起来更准确一些。但例外是昂贵的。像这样使用它们看起来是个坏主意。

  1. 使用数据库约束。但它看起来比(2)更混乱。

【问题讨论】:

  • 错误描述是一个应用程序/用户界面问题,不应该对您的域做任何事情。在您的域中抛出异常,在应用程序层中捕获它们并将其转换为可供用户使用的东西
  • @Tseng,你是说第二个变种吗?
  • 是的。并且异常并不昂贵,只有当您必须捕获它们时。如果它是一个 webservice/restapi,你已经应该做一些输入验证(当然不涉及业务逻辑),并且当输入验证错误时甚至不要调用域。当某些内容通过输入验证或无法在其中完成时(因为需要业务逻辑或数据库输入),就会出现异常

标签: validation domain-driven-design ddd-service


【解决方案1】:

让我们从第 3 点开始:数据库约束完成它们的工作。是的,异常/错误消息很混乱,我同意这一点。但问问自己:更混乱的是:向 1 个用户或 2 个具有相同电子邮件地址的用户帐户显示的可怕错误消息可能会破坏您的系统? DB 约束应该是你最后的安全网。您的服务需要检查是否已存在使用此电子邮件的用户帐户。但是,如果在另一个线程中,有人在您检查和创建新用户帐户之间的微秒内使用此电子邮件创建了一个用户帐户,会发生什么?您会对 DB 约束感到满意。 是的,您可以找到更好的解决方案,但这需要您有一个单例服务来序列化所有帐户创建,并确保没有两个线程可以同时创建用户帐户。

第 2 点:例外是针对特殊情况。有人想使用已使用的电子邮件创建用户帐户的情况是一种特殊情况。在有人想做脏事的情况下,不必担心代价高昂的操作。

第 1 点:我不喜欢这个。但那只是我的个人意见。在某些情况下,这种结果对象是有意义的,但我尽量将其保持在最低限度。

【讨论】:

  • 我的意思是它很乱,在应用程序/接口层捕获约束异常。至少对于描述的目标。
【解决方案2】:

不同的层可以有不同的方式来考虑和发出问题。仅仅因为基础设施引发异常并不意味着其他所有层都应该这样做。

你可以:

  • 基础设施:抛出重复密钥异常,因为客户端不会威胁数据库的完整性
  • 应用程序:捕获异常并返回一个简单的RegistrationResult.Failure 值,因为这是预期的失败案例
  • 演示:返回 HTTP 409 冲突

【讨论】:

    猜你喜欢
    • 2017-05-02
    • 1970-01-01
    • 1970-01-01
    • 2014-07-02
    • 1970-01-01
    • 2018-09-19
    • 1970-01-01
    • 1970-01-01
    • 2011-03-20
    相关资源
    最近更新 更多