Scalaz:如何链接未来[列表[A]],选项[A]和未来[选项[A]]并报告单个错误

时间:2016-05-15 15:23:51

标签: scala scalaz monad-transformers

loader = [class].getClass().getClassLoader()

上面的代码可以正常工作,当任何一个代码输入错误或输入错误时,如果任何代码无法获取信息,则返回Nil。我希望响应更具体的错误消息而不是空列表。例如,如果找不到HTTP请求中的params。我想告诉发件人HTTP params丢失或找不到给定的订单ID。使用EitherT或Either会有帮助吗?我该怎么办呢?感谢

更新1

我使用Scalaz (for { orderId <- ListT(extractParamFromHttp(request).toList) // extractParamFromHttp(request) returns Option[Long] order <- ListT(serviceA.retrieve(orderId).map(_.toList)) // serviceA.retrieve(...) returns Future[Option[Order]] items <- ListT(serviceB.retrieve(order.id).map(_.toList)) // serviceB.retrieve(...) returns Future[Seq[OrderItem]] } yield items).map(...) // convert items to JSON and return as Future[Result] EitherT(来自Either提示)解决了这个问题,并将此解决方案粘贴在此处进行了微小更改,

Validation

请参阅非Scalaz解决方案的答案

更新2

对于此解决方案或更精细解决方案的申请表(如果需要),请参阅here

1 个答案:

答案 0 :(得分:0)

我建议您抛弃scalaz,它对此用例没有任何价值,只会让您感到困惑。 不能保持简单通常是造成这种问题的原因。

def ifExists[T, R](opt: Option[T], err: String)(f: T => Future[R]) = 
  opt.fold(Future.failed(new IllegalArgumentException(err))(f)

for(
   order <- ifExists(extractParamFromHttp(request), "Missing param) {
     serviceA.retrieve(_)
   }
   items <- ifExists(order, "Order not found") { serviceB.retrieve(_) }
   result <- ...
) yield result

返回Future[Result],完成后将包含最终结果或指示失败原因的异常。 然后,调用者可以使用future.handle...检查异常,或使用future.transformfuture.onComplete

处理成功和失败