我正在使用 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