aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Warski <adam@warski.org>2017-12-27 18:24:02 +0100
committerGitHub <noreply@github.com>2017-12-27 18:24:02 +0100
commit21e8fabe936b751ba548f108e81adb31837a5060 (patch)
tree203c37fb81c03160cd03d31bb76a3f179e002e78
parent9174caf20dc28c66553dd0cce4b3287b0b2874c5 (diff)
parent763a9f0bdd43e360a9e8869efba99dec8f07eced (diff)
downloadsttp-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
-rw-r--r--core/src/main/scala/com/softwaremill/sttp/MonadError.scala9
-rw-r--r--core/src/main/scala/com/softwaremill/sttp/TryBackend.scala28
-rw-r--r--docs/backends/summary.rst1
-rw-r--r--tests/src/test/scala/com/softwaremill/sttp/BasicTests.scala4
-rw-r--r--tests/src/test/scala/com/softwaremill/sttp/testHelpers.scala6
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 =