Domain driven design 我的业务逻辑中的异常是否应该传播到我的控制器。

Domain driven design 我的业务逻辑中的异常是否应该传播到我的控制器。,domain-driven-design,software-design,solid-principles,Domain Driven Design,Software Design,Solid Principles,处理从业务逻辑发起的异常的最佳实践是什么。e、 g.当用例数据验证失败时 如果此异常传播到控制器,或者您在业务逻辑中处理它并向控制器返回更结构化的错误消息 有很多不同的实践,适用于不同的环境 在数据验证的情况下,您的代码路径通常不会到达业务逻辑 例如,假设我有一个web端点,该端点应该接受投标,其中每个投标消息都应该描述一个目标项目、投标价格和投标人等。如果消息是错误的——有人将日期放在出价应该是的位置,或者目标项id的格式错误,或者其他什么——那么通常的做法是将业务逻辑完全短路,就像您收到一个

处理从业务逻辑发起的异常的最佳实践是什么。e、 g.当用例数据验证失败时


如果此异常传播到控制器,或者您在业务逻辑中处理它并向控制器返回更结构化的错误消息

有很多不同的实践,适用于不同的环境

数据验证的情况下
,您的代码路径通常不会到达业务逻辑

例如,假设我有一个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)
任一解析(FormData-FormData)
BidMessage解析(FormData FormData)引发解析错误
无效解析(FormData FormData、BidMessageHandler onBid、ParseErrorHandler onError)
这个概念在几种不同的实现风格中工作

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

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

<> P>一个解决问题的方法是从存储库中考虑并行案例。我们正在从持久性应用装置中准备字节,不知何故,域模型需要理解这些字节——如果数据验证失败会发生什么


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

在这方面有不同的看法,因此我认为您不会得到“最佳实践”:

我更倾向于允许域中的异常一路传播到集成层,集成层是RESTAPI场景中的控制器。域中的异常实际上是一个“异常”,因此传回一些结构化的数据片段可能不是真正必要的。您可以选择使用某种约定或类似的方式向异常添加一些代码。然而,如果您正在处理特定的异常,您可能会有一个特定的类来表示该异常,在这种情况下,您确切地知道发生了什么。唯一的问题是,当这个单独的异常列表开始变得难以处理时

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

例如:

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

但这些将是实施细节。

谢谢@voiceOfUnreason的解释。但这不会影响独立测试业务逻辑的能力吗?如果我的测试用例有一个坏的bid消息(可能没有提供一个特定的必填字段),这可能会导致我的业务逻辑抛出某种异常。您能更具体地说明您所谈论的错误用例的类型吗?你认为“业务逻辑”属于哪一层?根据我的经验,用例输入数据验证(如:所需数据、最大长度等)不是通常在应用程序层进行的。