1

我正在使用http4s,并且我有一个Try为响应生成一些 json 数据:

case GET -> Root / "something" =>
   getSomethingTry() match {
    case Success(something) => Ok(something)
    case Failure(CustomNotFoundException(reason)) => NotFound(reason)
    case Failure(CustomConflictException()) => Conflict()
   }

此函数正确返回一个Task[Response]

但是,我想TryFuture. 匹配不再起作用,因为未来可能在匹配时尚未解决。所以,我可以映射未​​来:

case GET -> Root / "something" =>
   getSomethingFuture().map {
    something => Ok(something)
   }.recover {
    case CustomNotFoundException(reason) => NotFound(reason)
    case CustomConflictException() => Conflict()
   }

但这会返回 aFuture[Task[Response]]这不是 http4s 想要的。Await.result用它来拆箱似乎不合适Future——我认为这可能会导致线程池问题——但它确实使代码工作。

http4s 接受期货作为任务创建者的参数:

case GET -> Root / "something" =>
   Ok(getSomethingFuture())

但这并不能让我在出现不同错误时设置不同的状态码。一个解决方案可能是执行.recover一项任务,但我看不到一个明显的方法来做到这一点。

Future如果出现不同的失败情况,我如何调用不同的 http4s 任务包装器?我需要使用中间件吗?

4

2 回答 2

2

假设您使用的是http4s0.17 或更高版本,那么您Taskfs2.Task.

Future将其转换为Task然后处理后者很容易:

case GET -> Root / "something" =>
   Task.fromFuture(getSomethingFuture())
     .flatMap {
       something => Ok(something)
     }
     .handleWith {
       case CustomNotFoundException(reason) => NotFound(reason)
       case CustomConflictException() => Conflict()
     }

但是,我建议Task在整个程序中使用,而不是TryorFuture

于 2017-10-04T11:52:53.580 回答
-2

你真的不需要解开未来。Play 框架提供了用于返回 Future 的 action.async。

您可以通过以下方式使用它

Action.async {
  getSomethingFuture().map {
    something => Ok(something)
   }.recover {
    case CustomNotFoundException(reason) => NotFound(reason)
    case CustomConflictException() => Conflict()
   }
}

https://www.playframework.com/documentation/2.6.x/ScalaAsync#returning-futures

于 2017-10-04T13:17:09.833 回答