0

我正在使用 http4s & rho(主要用于 Swagger 集成)

我的服务正在使用这个 DAO 对象,该方法可以抛出异常(失败Task

case class BasicMatchDao() {
 def readAll(): Task[List[BasicMatch]] = Task.fail(ActionNotImplemented("readAll")) 
 def read(id: String): Task[Option[BasicMatch]] = readQuery(id).option.transact(xa)
}

在我的 RhoService 中,我可以像这样处理这些

private def exceptionToJson(t: Throwable):Json = Json.obj("error" -> t.getMessage.asJson)

val rhoService = new RhoService {
   GET / path |>> { (request: Request) =>
     Ok(dao.readAll.map(_.asJson)).handleWith {
        case t:ActionNotImplemented => NotImplemented(exceptionToJson(t))
        case t:Throwable => InternalServerError(exceptionToJson(t))
   }
} 

这样我可以确保无论我返回什么,它总是一个Json

因为我不想用类似的错误处理来污染每个 RhoRoute,所以我想做一些使用默认 http4s.dsl 可能的事情,但我似乎无法使用 rho:

1.创建默认错误处理程序

例如添加

 ...
 Ok(dao.readAll.map(_.asJson)).handleWith(errorHandler)
 ...

private def errorHandler(): PartialFunction[Throwable, Task[Response]] = {
      case t:ActionNotImplemented => NotImplemented(exceptionToJson(t))
      case t:Throwable => InternalServerError(exceptionToJson(t))
}

这将失败,因为 NotImplemented 不是响应(我可以在这些上调用 .pure 以进行类型检查)但是代码将编译,但我得到了这个异常:

无法从 fs2.Task[Product with Serializable] 转换为实体,因为找不到 EntityEncoder[fs2.Task[Product with Serializable]] 实例。好的(dao.readAll.map(_.asJson)).handleWith(errorHandler)

2.为每个RhoRoute添加errorhandler

在定义 rhoRoute 之后,我想映射它并将错误处理程序添加到每条路由,所以在 r 处做一些事情,让我在某处添加“handleWith”(下面将不起作用)

 new RhoService(rhoService.getRoutes.map(_.handleWith(errorHandler))

如果我不能让它工作,我可能会回到默认的 dsl,但我真的很喜欢 rho

4

1 回答 1

0

所以第 1 部分现在已修复。将任务定义为Task[BaseResult]而不是Task[Response]将起作用

import org.http4s.rho.Result.BaseResult

val errorHandler: PartialFunction[Throwable, Task[BaseResult]] = {
    case t:ActionNotImplemented => NotImplemented(exceptionToJson(t))
    case t:Throwable => InternalServerError(exceptionToJson(t))
  }

我也在研究第2部分。欢迎所有帮助:-)

于 2017-09-27T07:48:26.497 回答