我正在使用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。创建默认错误处理程序
e.g。添加
...
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 [带可序列化的产品] 到一个实体,因为没有EntityEncoder [fs2.Task [产品有 可以找到Serializable]]实例。 OK(dao.readAll.map(_。asJson))。handleWith函数(errorHandler)
2。将错误处理程序添加到每个RhoRoute
在定义了rhoRoute之后我想在它上面映射并为每条路线添加错误处理程序,所以在r处做一些让我自己添加' handleWith'某处(下面不起作用)
new RhoService(rhoService.getRoutes.map(_.handleWith(errorHandler))
如果我无法使用此功能,我可能会回到默认的dsl,但我真的很喜欢rho
答案 0 :(得分: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部分。欢迎所有帮助: - )