处理从业务逻辑发起的异常的最佳做法是什么。例如用例数据验证失败时。
此异常是否会传播到您的控制器,或者您在业务逻辑中处理它并向控制器返回更结构化的错误消息。
答案 0 :(得分:0)
有许多不同的做法,适用于不同的背景。
对于data validation
,您的代码路径通常不会达到业务逻辑。
例如,假设我有一个应该接受bids
的网络端点,其中每个出价消息应描述目标项目,出价和投标人等。如果消息是错误的 - 有人提出了一个应该是出价的日期,或者目标项目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)
这个概念适用于几种不同的实现方式。
但这不会影响能够独立测试业务逻辑吗?
我不这么认为?测试装备可以像应用程序一样轻松地创建消息。
构建问题的一种方法是从存储库中考虑并行案例。我们正在从持久性设备中读取字节,并且域模型需要以某种方式理解这些字节 - 如果 数据验证失败会发生什么?
让存储库抽象出存储问题的部分原因在于它允许业务逻辑完全免除它们。我们希望从输入的实现问题中获得相同的隔离。
答案 1 :(得分:0)
对此有不同的看法,所以我不认为你会得到一个&#34;最佳实践&#34; :)
我更倾向于允许我的域中的异常一直传播到集成层,这是rest-api场景中的控制器。域中的例外实际上是&#34;异常&#34;所以传回一些结构化的数据可能并不是必需的。您可能选择使用某些约定或某些约定向您的异常添加一些代码。但是,如果您正在处理特定的异常,则可能有一个特定的类表示该异常,在这种情况下您确切知道发生了什么。唯一的问题是当这个单独的例外列表开始变得难以处理时。
我倾向于使用通用BusinessException
。例如,对于您想要本地化消息的情况,您可能需要将消息包含一些编码数据:
例如:
throw new BusinessException("[BC-Account-Invalid-E-Mail]: Invalid e-mail address specified.");
但这些将是实施细节。