Scalaz:如何链接Future [List [A]],Option [A]和Future [Option [A]]并报告单个错误

苗条
(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]

上面的代码可以正常工作,并且如果输入不正确或缺少输入,则它们中的任何一个都无法获取信息时,它将返回Nil。我想用更具体的错误消息而不是空列表进行响应。例如,如果找不到HTTP请求中的参数。我想告诉发送者,HTTP参数丢失或找不到给定的订单ID。使用EitherT或Either会有所帮助吗?我该怎么办?谢谢

更新1

我使用ScalazEitherTEither(来自的提示Validation解决了问题,并将我的解决方案进行了微小的更改,

import scalaz._
import Scalaz._
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

case class Order(id: Long, desc: String)
case class Vendor(id: Long, name: String)

def extractHeader(valid: Boolean): Option[String] = if (valid) Some("bob") else None
def retrieveVendor(username: String, found: Boolean): Future[Option[Vendor]] = 
  if (found) Future.successful(Some(Vendor(103, "Bob Enterprise"))) else Future.successful(None)
def retrieveOrders(vendorId: Long, found: Boolean): Future[List[Order]] =
  if (found) Future.successful(List(Order(1, "Product 1"), Order(2, "Product 2"))) else Future.successful(List.empty[Order])

def output(result: Future[\/[String, AnyRef]]) = result.foreach {
  case -\/(s) => println(s"Error: $s")
  case \/-(ys @ x :: xs) => println(ys)
  case \/-(s) => println(s)
}

def orders(valid: Boolean, userFound: Boolean, vendorFound: Boolean) = for {
  username <- EitherT(Future.successful(extractHeader(valid) \/> "Bad headers"))   // Option[String]
  vendor <- EitherT(retrieveVendor(username, userFound).map(_ \/> "Bad username")) // Future[Option[Vendor]]
  orders <- EitherT(retrieveOrders(vendor.id, vendorFound).map {                   // Future[Seq[Order]]    
    case Nil => "Bad vendor".left
    case xs => xs.right
  })                                                                              
} yield orders

output(orders(false,false, true).run)

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

更新2

有关此解决方案或更详尽的解决方案的适用形式(如果需要),请参阅此处

迪玛

我建议您抛弃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

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在Scalaz中将Future [Option [List [List [Double]]]更改为Future [Option [List [List [Double]]]]

来自分类Dev

`Future [Option [Future [Option [X]]]]`转换为`Future [Option [X]]`

来自分类Dev

在 slick 中理解的 Future 和 Option

来自分类Dev

使用Option()的Scala Future

来自分类Dev

如何在Scala中展平未来-“ val _2flat:Future [Option [Future [List [Long]]]]

来自分类Dev

将`Future [Option [X]]`转换为`Option [Future [X]]`

来自分类Dev

如何将Future [Option [(Person,Future [Vector [Order]]]]]]转换为Future [Option [(Person,Vector [Order]]]]]

来自分类Dev

展平Future的Option部分

来自分类Dev

我应该如何加入Option [Future [T]]?

来自分类Dev

Scala:将Future [Option [List [User]]]转换为Future [Map [Long,User]]

来自分类Dev

正在播放的Future [Option [BasicProfile]]方法上的编译错误

来自分类Dev

正在播放的Future [Option [BasicProfile]]方法上的编译错误

来自分类Dev

如何在给定的 Future[Try[Option[A]]] 上应用类型 A => Future[Try[Option[B]]] 的函数?

来自分类Dev

找到:scala.concurrent.Future [Option [Int]]必需:Option [?]

来自分类Dev

理解中的Future [Option [Boolean]]。简单吧?

来自分类Dev

了解reactMongo中的Future [Option [T]]

来自分类Dev

在 Scala 中解包 Future[Option[MyType]]

来自分类Dev

在Scala中,如何为Future [Option [A]]进行类型转换?

来自分类Dev

将Future [T]转换为永远成功的Future [Option [T]]

来自分类Dev

将Future [MyType]转换为Future [Option [MyType]]

来自分类Dev

用于理解Future [Option [T]]并根据条件执行后续的Future

来自分类Dev

如何为Option [List [_]] n Scala定义<*>

来自分类Dev

如何toString()这样的列表:List <Option>?

来自分类Dev

Scalaz .option - what is this shorthand for?

来自分类Dev

Option.zip returns List, not Option

来自分类Dev

从Future [Option [Int]]获取Int值的优雅方法

来自分类Dev

Actor返回Future [Option [None]] Akka Http时抛出异常

来自分类Dev

如何在AKKA-HTTP中将Future [Option [Foo]]类编组为JSON

来自分类Dev

Scala 类型不匹配:发现 Future[MyType] 需要 Future[Option[MyType]]

Related 相关文章

  1. 1

    在Scalaz中将Future [Option [List [List [Double]]]更改为Future [Option [List [List [Double]]]]

  2. 2

    `Future [Option [Future [Option [X]]]]`转换为`Future [Option [X]]`

  3. 3

    在 slick 中理解的 Future 和 Option

  4. 4

    使用Option()的Scala Future

  5. 5

    如何在Scala中展平未来-“ val _2flat:Future [Option [Future [List [Long]]]]

  6. 6

    将`Future [Option [X]]`转换为`Option [Future [X]]`

  7. 7

    如何将Future [Option [(Person,Future [Vector [Order]]]]]]转换为Future [Option [(Person,Vector [Order]]]]]

  8. 8

    展平Future的Option部分

  9. 9

    我应该如何加入Option [Future [T]]?

  10. 10

    Scala:将Future [Option [List [User]]]转换为Future [Map [Long,User]]

  11. 11

    正在播放的Future [Option [BasicProfile]]方法上的编译错误

  12. 12

    正在播放的Future [Option [BasicProfile]]方法上的编译错误

  13. 13

    如何在给定的 Future[Try[Option[A]]] 上应用类型 A => Future[Try[Option[B]]] 的函数?

  14. 14

    找到:scala.concurrent.Future [Option [Int]]必需:Option [?]

  15. 15

    理解中的Future [Option [Boolean]]。简单吧?

  16. 16

    了解reactMongo中的Future [Option [T]]

  17. 17

    在 Scala 中解包 Future[Option[MyType]]

  18. 18

    在Scala中,如何为Future [Option [A]]进行类型转换?

  19. 19

    将Future [T]转换为永远成功的Future [Option [T]]

  20. 20

    将Future [MyType]转换为Future [Option [MyType]]

  21. 21

    用于理解Future [Option [T]]并根据条件执行后续的Future

  22. 22

    如何为Option [List [_]] n Scala定义<*>

  23. 23

    如何toString()这样的列表:List <Option>?

  24. 24

    Scalaz .option - what is this shorthand for?

  25. 25

    Option.zip returns List, not Option

  26. 26

    从Future [Option [Int]]获取Int值的优雅方法

  27. 27

    Actor返回Future [Option [None]] Akka Http时抛出异常

  28. 28

    如何在AKKA-HTTP中将Future [Option [Foo]]类编组为JSON

  29. 29

    Scala 类型不匹配:发现 Future[MyType] 需要 Future[Option[MyType]]

热门标签

归档