diff options
author | adamw <adam@warski.org> | 2017-11-16 12:22:50 +0100 |
---|---|---|
committer | adamw <adam@warski.org> | 2017-11-16 12:22:50 +0100 |
commit | 837c1a12d9bcf88e3d1055de7e1673a1b92bbe21 (patch) | |
tree | 520bb1e75f420048bc8d270e4fe395afd78f7206 /core | |
parent | 585bfcc741109bef5c534ce245811595062af086 (diff) | |
download | sttp-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.scala | 16 |
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] = { |