使用rho在http4s中添加异常处理

时间:2017-09-26 12:46:50

标签: scala http4s

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

1 个答案:

答案 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部分。欢迎所有帮助: - )