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 は Response ではないため、これは失敗します (これらに対して .pure を呼び出して型チェックを機能させることができます)。ただし、コードはコンパイルされますが、次の例外が発生します。
EntityEncoder[fs2.Task[シリアル化可能な製品]] インスタンスが見つからなかったため、fs2.Task[シリアル化可能な製品] からエンティティに変換できません。OK(dao.readAll.map(_.asJson)).handleWith(errorHandler)
2. 各 RhoRoute にエラーハンドラーを追加する
rhoRoute を定義した後、それをマッピングして各ルートにエラー ハンドラを追加したいので、r で何かを実行して、「handleWith」をどこかに追加できるようにします (以下は機能しません)。
new RhoService(rhoService.getRoutes.map(_.handleWith(errorHandler))
これが機能しない場合は、おそらくデフォルトの DSL に戻しますが、rho が本当に気に入りました。