2017-09-26 31 views
0

我使用http4s & RHO(主要爲揚鞭集成)在http4s添加異常處理與RHO

我的服務都採用這種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污染具有類似ErrorHandling中我想要做的事是可能的默認http4s.dsl,但我可以「T似乎得到與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不是響應(我可以打電話。純對這些進行類型檢查工作) 但隨後的代碼編譯,但我得到這個異常:

無法從fs2.Task [帶序列化的產品] 轉換爲實體,因爲沒有找到EntityEncoder [fs2.Task [帶有 可序列化的實例]]實例。 好(dao.readAll.map(_。asJson))。handleWith函數(errorHandler)

2.添加的ErrorHandler到每個RhoRoute

定義rhoRoute後,我想在映射它和的ErrorHandler添加到每個路線,所以做於R,讓是我加入「handleWith」某處(以下將無法正常工作)

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

如果我不能得到這個工作的東西,我可能會回到默認的dsl,但我真的很喜歡rho

回答

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部分爲好。歡迎所有幫助:-)