diff options
author | Adam Warski <adam@warski.org> | 2017-12-27 18:24:02 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-27 18:24:02 +0100 |
commit | 21e8fabe936b751ba548f108e81adb31837a5060 (patch) | |
tree | 203c37fb81c03160cd03d31bb76a3f179e002e78 | |
parent | 9174caf20dc28c66553dd0cce4b3287b0b2874c5 (diff) | |
parent | 763a9f0bdd43e360a9e8869efba99dec8f07eced (diff) | |
download | sttp-21e8fabe936b751ba548f108e81adb31837a5060.tar.gz sttp-21e8fabe936b751ba548f108e81adb31837a5060.tar.bz2 sttp-21e8fabe936b751ba548f108e81adb31837a5060.zip |
Merge pull request #56 from joshlemer/try-monad-error
Add TryMonad, implement a delegating TryBackend
5 files changed, 48 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 77c6235..5751382 100644 --- a/core/src/main/scala/com/softwaremill/sttp/MonadError.scala +++ b/core/src/main/scala/com/softwaremill/sttp/MonadError.scala @@ -41,7 +41,16 @@ object IdMonad extends MonadError[Id] { override protected def handleWrappedError[T](rt: Id[T])( h: PartialFunction[Throwable, Id[T]]): Id[T] = rt } +object TryMonad extends MonadError[Try] { + override def unit[T](t: T): Try[T] = Success(t) + override def map[T, T2](fa: Try[T])(f: (T) => T2): Try[T2] = fa.map(f) + override def flatMap[T, T2](fa: Try[T])(f: (T) => Try[T2]): Try[T2] = + fa.flatMap(f) + override def error[T](t: Throwable): Try[T] = Failure(t) + override protected def handleWrappedError[T](rt: Try[T])( + h: PartialFunction[Throwable, Try[T]]): Try[T] = rt.recoverWith(h) +} class FutureMonad(implicit ec: ExecutionContext) extends MonadAsyncError[Future] { diff --git a/core/src/main/scala/com/softwaremill/sttp/TryBackend.scala b/core/src/main/scala/com/softwaremill/sttp/TryBackend.scala new file mode 100644 index 0000000..7ec864f --- /dev/null +++ b/core/src/main/scala/com/softwaremill/sttp/TryBackend.scala @@ -0,0 +1,28 @@ +package com.softwaremill.sttp + +import java.net.HttpURLConnection + +import scala.util.Try + +/** A Backend that safely wraps SttpBackend exceptions in Try's + * + * @param delegate An SttpBackend which to which this backend forwards all requests + * @tparam S The type of streams that are supported by the backend. `Nothing`, + * if streaming requests/responses is not supported by this backend. + */ +class TryBackend[-S](delegate: SttpBackend[Id, S]) extends SttpBackend[Try, S] { + override def send[T](request: Request[T, S]): Try[Response[T]] = + Try(delegate.send(request)) + + override def close(): Unit = delegate.close() + + override def responseMonad: MonadError[Try] = TryMonad +} + +object TryHttpUrlConnectionBackend { + def apply(options: SttpBackendOptions = SttpBackendOptions.Default, + customizeConnection: HttpURLConnection => Unit = _ => ()) + : SttpBackend[Try, Nothing] = + new TryBackend[Nothing]( + HttpURLConnectionBackend(options, customizeConnection)) +} diff --git a/docs/backends/summary.rst b/docs/backends/summary.rst index d58bb54..72b20c9 100644 --- a/docs/backends/summary.rst +++ b/docs/backends/summary.rst @@ -18,6 +18,7 @@ Below is a summary of all the backends. See the sections on individual backend i Class Response wrapper Supported stream type ================================ ============================ ================================================ ``HttpURLConnectionBackend`` None (``Id``) n/a +``TryHttpURLConnectionBackend`` ``scala.util.Try`` n/a ``AkkaHttpBackend`` ``scala.concurrent.Future`` ``akka.stream.scaladsl.Source[ByteString, Any]`` ``AsyncHttpClientFutureBackend`` ``scala.concurrent.Future`` n/a ``AsyncHttpClientScalazBackend`` ``scalaz.concurrent.Task`` n/a diff --git a/tests/src/test/scala/com/softwaremill/sttp/BasicTests.scala b/tests/src/test/scala/com/softwaremill/sttp/BasicTests.scala index af5c5ae..3d38082 100644 --- a/tests/src/test/scala/com/softwaremill/sttp/BasicTests.scala +++ b/tests/src/test/scala/com/softwaremill/sttp/BasicTests.scala @@ -197,6 +197,10 @@ class BasicTests runTests("HttpURLConnection")(HttpURLConnectionBackend(), ForceWrappedValue.id) + + runTests("TryHttpURLConnection")(TryHttpUrlConnectionBackend(), + ForceWrappedValue.scalaTry) + runTests("Akka HTTP")(AkkaHttpBackend.usingActorSystem(actorSystem), ForceWrappedValue.future) runTests("Async Http Client - Future")(AsyncHttpClientFutureBackend(), diff --git a/tests/src/test/scala/com/softwaremill/sttp/testHelpers.scala b/tests/src/test/scala/com/softwaremill/sttp/testHelpers.scala index 4eea904..c926840 100644 --- a/tests/src/test/scala/com/softwaremill/sttp/testHelpers.scala +++ b/tests/src/test/scala/com/softwaremill/sttp/testHelpers.scala @@ -15,6 +15,7 @@ import org.scalatest.{BeforeAndAfterAll, Suite} import scala.concurrent.Future import scala.concurrent.duration._ import scala.language.higherKinds +import scala.util.Try import scalaz._ trait TestHttpServer @@ -50,6 +51,11 @@ object ForceWrappedValue extends ScalaFutures with TestingPatience { override def force[T](wrapped: Id[T]): T = wrapped } + + val scalaTry = new ForceWrappedValue[Try] { + override def force[T](wrapped: Try[T]): T = wrapped.get + } + val future = new ForceWrappedValue[Future] { override def force[T](wrapped: Future[T]): T = |