Skip to content

Commit

Permalink
Make TooManyRedirectsException part of the read exception hierarchy (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
adamw authored Jan 13, 2025
1 parent cb4124b commit e992977
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 11 deletions.
4 changes: 4 additions & 0 deletions core/src/main/scala/sttp/client4/SttpClientException.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package sttp.client4

import sttp.monad.MonadError
import sttp.model.Uri

/** Known exceptions that might occur when using a backend. Currently this covers:
* - connect exceptions: when a connection (tcp socket) can't be established to the target host
Expand Down Expand Up @@ -28,6 +29,9 @@ object SttpClientException extends SttpClientExceptionExtensions {

class TimeoutException(request: GenericRequest[_, _], cause: Exception) extends ReadException(request, cause)

class TooManyRedirectsException(request: GenericRequest[_, _], val redirects: Int)
extends ReadException(request, null)

def adjustExceptions[F[_], T](
monadError: MonadError[F]
)(t: => F[T])(usingFn: Exception => Option[Exception]): F[T] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ abstract class FollowRedirectsBackend[F[_], P] private (
): F[Response[T]] =
response.header(HeaderNames.Location).fold(monad.unit(response)) { loc =>
if (redirects >= request.options.maxRedirects) {
monad.error(TooManyRedirectsException(request.uri, redirects))
monad.error(new SttpClientException.TooManyRedirectsException(request, redirects))
} else {
followRedirect(request, response, redirects, loc)
}
Expand Down Expand Up @@ -121,8 +121,6 @@ object FollowRedirectsBackend {
val DefaultUriTransform: Uri => Uri = (uri: Uri) => uri
}

case class TooManyRedirectsException(uri: Uri, redirects: Int) extends Exception

/** @param transformUri
* Defines if and how [[Uri]] s from the `Location` header should be transformed. For example, this enables changing
* the encoding of host, path, query and fragment segments to be more strict or relaxed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import sttp.model.{Header, HeaderNames, StatusCode}
import scala.concurrent.Future
import HttpTest.endpoint
import org.scalatest.freespec.AsyncFreeSpecLike
import sttp.client4.wrappers.{DigestAuthenticationBackend, FollowRedirectsBackend, TooManyRedirectsException}
import sttp.client4.wrappers.{DigestAuthenticationBackend, FollowRedirectsBackend}
import sttp.model.headers.CookieWithMeta
import sttp.model.Encodings
import java.util.zip.GZIPInputStream
Expand Down Expand Up @@ -132,17 +132,17 @@ trait HttpTestExtensions[F[_]] extends AsyncFreeSpecLike { self: HttpTest[F] =>
"break redirect loops" in {
// sync backends can throw exceptions when evaluating send(), before the toFuture() conversion
Future(loop.send(backend).toFuture()).flatMap(identity).failed.map {
case TooManyRedirectsException(_, redirects) =>
redirects shouldBe FollowRedirectsBackend.MaxRedirects
case e: SttpClientException.TooManyRedirectsException =>
e.redirects shouldBe FollowRedirectsBackend.MaxRedirects
case e => fail(e)
}
}

"break redirect loops after user-specified count" in {
val maxRedirects = 10
Future(loop.maxRedirects(maxRedirects).send(backend).toFuture()).flatMap(identity).failed.collect {
case TooManyRedirectsException(_, redirects) =>
redirects shouldBe maxRedirects
case e: SttpClientException.TooManyRedirectsException =>
e.redirects shouldBe maxRedirects
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package sttp.client4.testing

import org.scalatest.freespec.AnyFreeSpecLike
import sttp.client4._
import sttp.client4.wrappers.{FollowRedirectsBackend, TooManyRedirectsException}
import sttp.client4.wrappers.FollowRedirectsBackend
import sttp.model.{Header, StatusCode}

import java.io.File
Expand Down Expand Up @@ -38,14 +38,14 @@ trait SyncHttpTestExtensions extends AnyFreeSpecLike {
}

"break redirect loops" in {
intercept[TooManyRedirectsException] {
intercept[SttpClientException.TooManyRedirectsException] {
loop.send(backend)
}.redirects shouldBe FollowRedirectsBackend.MaxRedirects
}

"break redirect loops after user-specified count" in {
val maxRedirects = 10
intercept[TooManyRedirectsException] {
intercept[SttpClientException.TooManyRedirectsException] {
loop.maxRedirects(maxRedirects).send(backend)
}.redirects shouldBe maxRedirects
}
Expand Down

0 comments on commit e992977

Please sign in to comment.