【问题标题】:Should Exception from my Business logic ever propagate to my controller.我的业务逻辑中的异常是否应该传播到我的控制器。
【发布时间】:2018-06-17 12:21:59
【问题描述】:

处理业务逻辑引发的异常的最佳做法是什么。例如当用例数据验证失败时。

这个异常应该传播到您的控制器,还是您在业务逻辑中处理它并向控制器返回更结构化的错误消息。

【问题讨论】:

  • 您能否更具体地说明您所说的错误案例类型?您通过“业务逻辑”管理哪一层?根据我的经验,用例输入数据验证(如:所需数据、最大长度等)不是您通常在应用程序层执行的操作。

标签: domain-driven-design software-design solid-principles


【解决方案1】:

对此有不同的看法,所以我认为您不会获得“最佳实践”:)

我更倾向于允许我的域中的异常一直传播到集成层,集成层是 rest-api 场景中的控制器。域中的异常确实是“异常”,因此可能不需要传回一些结构化的数据。您可以选择使用某种约定或类似的约定将一些代码添加到您的异常中。但是,如果您正在处理特定的异常,您可能有一个特定的类来表示该异常,在这种情况下您确切地知道发生了什么。唯一的问题是当这个单独的例外列表开始变得笨拙时。

我倾向于使用通用的BusinessException。例如,对于您想要本地化消息的情况,您可能需要让消息包含一些编码数据:

例如:

throw new BusinessException("[BC-Account-Invalid-E-Mail]: Invalid e-mail address specified.");

但这些将是实现细节。

【讨论】:

    【解决方案2】:

    有很多不同的做法,适用于不同的环境。

    对于data validation,您的代码路径通常不会到达业务逻辑。

    例如,假设我有一个应该接受bids 的 Web 端点,其中每个投标消息都应该描述一个目标项目、一个投标价格和一个投标人等等。如果消息是错误的——有人输入了一个应该是投标价格的日期,或者目标项目 ID 的格式错误,或者其他什么——那么通常的做法是完全将业务逻辑短路到循环之外,就像您收到带有无法识别方法的 HTTP 请求消息一样。

    FormData -> BidMessage | ParseError
    

    是基本思想。

    Either<BidMessage, ParseError> parse(FormData formData)
    BidMessage parse(FormData formData) throws ParseError
    void parse(FormData formData, BidMessageHandler onBid, ParseErrorHandler onError)
    

    这个概念适用于几种不同的实现风格。

    但这不会影响独立测试业务逻辑的能力吗?

    我不这么认为?测试台可以像应用程序一样轻松地创建消息。

    提出问题的一种方法是考虑存储库中的并行案例。我们正在从持久性设备中准备好字节,并且以某种方式需要域模型理解这些字节——如果那个数据验证失败会发生什么?

    让存储库抽象出存储问题的部分原因在于它允许业务逻辑完全摆脱它们。我们希望与输入的实现关注点保持同样的隔离。

    【讨论】:

    • 感谢@voiceOfUnreason 的解释。但这不会影响独立测试业务逻辑的能力吗?如果我的测试用例有错误的出价消息(可能未提供特定的必填字段),这可能会导致我的业务逻辑抛出一些异常。
    猜你喜欢
    • 2021-03-28
    • 2011-06-28
    • 2016-04-22
    • 2011-06-01
    • 2013-03-14
    • 2010-09-19
    • 2017-08-08
    • 1970-01-01
    • 2012-05-20
    相关资源
    最近更新 更多