diff --git a/docs/dsl/middleware.md b/docs/dsl/middleware.md index 3260835ff9..6a357e632f 100644 --- a/docs/dsl/middleware.md +++ b/docs/dsl/middleware.md @@ -92,7 +92,7 @@ import zio.http._ // compose basic auth, request/response logging, timeouts middlewares val composedMiddlewares = Middleware.basicAuth("user","pw") ++ Middleware.debug ++ - RouteAspect.timeout(5.seconds) + RoutesAspect.timeout(5.seconds) ``` And then we can attach our composed bundle of middlewares to an Http using `@@` diff --git a/zio-http/src/main/scala/zio/http/Handler.scala b/zio-http/src/main/scala/zio/http/Handler.scala index 645d4589e7..b6f76e3ccd 100644 --- a/zio-http/src/main/scala/zio/http/Handler.scala +++ b/zio-http/src/main/scala/zio/http/Handler.scala @@ -364,8 +364,14 @@ sealed trait Handler[-R, +Err, -In, +Out] { self => final def mapError[Err1](f: Err => Err1)(implicit trace: Trace): Handler[R, Err1, In, Out] = self.foldHandler(err => Handler.fail(f(err)), Handler.succeed(_)) + /** + * Transforms all failures except pure interruption. + */ final def mapErrorCause[Err2](f: Cause[Err] => Err2)(implicit trace: Trace): Handler[R, Err2, In, Out] = - self.foldCauseHandler(err => Handler.fail(f(err)), Handler.succeed(_)) + self.foldCauseHandler( + err => if (err.isInterruptedOnly) Handler.failCause(err.asInstanceOf[Cause[Nothing]]) else Handler.fail(f(err)), + Handler.succeed(_), + ) /** * Transforms the output of the handler effectfully diff --git a/zio-http/src/test/scala/zio/http/RoutePatternSpec.scala b/zio-http/src/test/scala/zio/http/RoutePatternSpec.scala index e597ae65dc..4e02de5666 100644 --- a/zio-http/src/test/scala/zio/http/RoutePatternSpec.scala +++ b/zio-http/src/test/scala/zio/http/RoutePatternSpec.scala @@ -141,6 +141,19 @@ object RoutePatternSpec extends ZIOSpecDefault { assertTrue(tree.get(Method.GET, Path("/users/123")).contains(1)) }, + test("more specific beats less specific") { + var tree: Tree[Int] = RoutePattern.Tree.empty + + val pattern1 = Method.ANY / "users" + val pattern2 = Method.OPTIONS / "users" + val pattern3 = Method.ANY / "users" + + tree = tree.add(pattern1, 1) + tree = tree.add(pattern2, 2) + tree = tree.add(pattern3, 3) + + assertTrue(tree.get(Method.OPTIONS, Path("/users")) == Chunk(2, 1, 3)) + }, test("multiple routes") { var tree: Tree[Unit] = RoutePattern.Tree.empty diff --git a/zio-http/src/test/scala/zio/http/StaticFileServerSpec.scala b/zio-http/src/test/scala/zio/http/StaticFileServerSpec.scala index 65842259e6..1a0ccd08da 100644 --- a/zio-http/src/test/scala/zio/http/StaticFileServerSpec.scala +++ b/zio-http/src/test/scala/zio/http/StaticFileServerSpec.scala @@ -82,7 +82,7 @@ object StaticFileServerSpec extends HttpRunnableSpec { val tmpFile = File.createTempFile("test", "txt") tmpFile.setReadable(false) val res = Handler.fromFile(tmpFile).sandbox.toHttpApp.deploy.run().map(_.status) - assertZIO(res)(equalTo(Status.InternalServerError)) + assertZIO(res)(equalTo(Status.Forbidden)) } @@ unix, ), suite("invalid file")( diff --git a/zio-http/src/test/scala/zio/http/StaticServerSpec.scala b/zio-http/src/test/scala/zio/http/StaticServerSpec.scala index e77a353f2f..cede686481 100644 --- a/zio-http/src/test/scala/zio/http/StaticServerSpec.scala +++ b/zio-http/src/test/scala/zio/http/StaticServerSpec.scala @@ -82,7 +82,7 @@ object StaticServerSpec extends HttpRunnableSpec { ) override def spec = - suite("Server") { + suite("StaticServerSpec") { app .as( List(staticAppSpec, nonZIOSpec, throwableAppSpec, multiHeadersSpec),