Добавьте обработку исключений в http4s с помощью rho
Я использую 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 для них, чтобы заставить проверку типов работать) Но тогда код скомпилируется, но я получаю это исключение:
Невозможно преобразовать из fs2.Task[Product with Serializable] в Entity, поскольку не найден экземпляр EntityEncoder[fs2.Task[Product with Serializable]]. Ok(dao.readAll.map(_. AsJson)). HandleWith(ErrorHandler)
2. Добавьте обработчик ошибок к каждому RhoRoute
После определения rhoRoute я хотел бы отобразить его и добавить обработчик ошибок к каждому маршруту, поэтому сделайте что-то в r, что позволит мне добавить где-нибудь handleWith(ниже не будет работать)
new RhoService(rhoService.getRoutes.map(_.handleWith(errorHandler))
Если я не могу заставить это работать, я, вероятно, вернусь к стандартному dsl, но мне действительно понравился rho
1 ответ
Итак, часть 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, а также. Любая помощь приветствуется:-)