aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authoradamw <adam@warski.org>2017-11-16 12:22:50 +0100
committeradamw <adam@warski.org>2017-11-16 12:22:50 +0100
commit837c1a12d9bcf88e3d1055de7e1673a1b92bbe21 (patch)
tree520bb1e75f420048bc8d270e4fe395afd78f7206 /core
parent585bfcc741109bef5c534ce245811595062af086 (diff)
downloadsttp-837c1a12d9bcf88e3d1055de7e1673a1b92bbe21.tar.gz
sttp-837c1a12d9bcf88e3d1055de7e1673a1b92bbe21.tar.bz2
sttp-837c1a12d9bcf88e3d1055de7e1673a1b92bbe21.zip
Add the possibility for monads to recover from errors
Diffstat (limited to 'core')
-rw-r--r--core/src/main/scala/com/softwaremill/sttp/MonadError.scala16
1 files changed, 16 insertions, 0 deletions
diff --git a/core/src/main/scala/com/softwaremill/sttp/MonadError.scala b/core/src/main/scala/com/softwaremill/sttp/MonadError.scala
index 34edb0a..77c6235 100644
--- a/core/src/main/scala/com/softwaremill/sttp/MonadError.scala
+++ b/core/src/main/scala/com/softwaremill/sttp/MonadError.scala
@@ -8,7 +8,17 @@ trait MonadError[R[_]] {
def unit[T](t: T): R[T]
def map[T, T2](fa: R[T])(f: T => T2): R[T2]
def flatMap[T, T2](fa: R[T])(f: T => R[T2]): R[T2]
+
def error[T](t: Throwable): R[T]
+ protected def handleWrappedError[T](rt: R[T])(
+ h: PartialFunction[Throwable, R[T]]): R[T]
+ def handleError[T](rt: => R[T])(h: PartialFunction[Throwable, R[T]]): R[T] = {
+ Try(rt) match {
+ case Success(v) => handleWrappedError(v)(h)
+ case Failure(e) if h.isDefinedAt(e) => h(e)
+ case Failure(e) => error(e)
+ }
+ }
def flatten[T](ffa: R[R[T]]): R[T] = flatMap[R[T], T](ffa)(identity)
@@ -26,7 +36,10 @@ object IdMonad extends MonadError[Id] {
override def unit[T](t: T): Id[T] = t
override def map[T, T2](fa: Id[T])(f: (T) => T2): Id[T2] = f(fa)
override def flatMap[T, T2](fa: Id[T])(f: (T) => Id[T2]): Id[T2] = f(fa)
+
override def error[T](t: Throwable): Id[T] = throw t
+ override protected def handleWrappedError[T](rt: Id[T])(
+ h: PartialFunction[Throwable, Id[T]]): Id[T] = rt
}
class FutureMonad(implicit ec: ExecutionContext)
@@ -36,7 +49,10 @@ class FutureMonad(implicit ec: ExecutionContext)
override def map[T, T2](fa: Future[T])(f: (T) => T2): Future[T2] = fa.map(f)
override def flatMap[T, T2](fa: Future[T])(f: (T) => Future[T2]): Future[T2] =
fa.flatMap(f)
+
override def error[T](t: Throwable): Future[T] = Future.failed(t)
+ override protected def handleWrappedError[T](rt: Future[T])(
+ h: PartialFunction[Throwable, Future[T]]): Future[T] = rt.recoverWith(h)
override def async[T](
register: ((Either[Throwable, T]) => Unit) => Unit): Future[T] = {