From 798c17f9134498ccafd9e62a39b617dd7d9456b4 Mon Sep 17 00:00:00 2001 From: Jorge Aliss Date: Sun, 24 Sep 2023 16:39:43 -0300 Subject: [PATCH] Add missing traces to the http package (#2354) --- .../src/main/scala/zio/http/Handler.scala | 2 +- .../src/main/scala/zio/http/HttpApp.scala | 10 ++-- zio-http/src/main/scala/zio/http/Route.scala | 21 ++++---- zio-http/src/main/scala/zio/http/Routes.scala | 11 ++-- .../src/main/scala/zio/http/ZClient.scala | 52 ++++++++++--------- 5 files changed, 51 insertions(+), 45 deletions(-) diff --git a/zio-http/src/main/scala/zio/http/Handler.scala b/zio-http/src/main/scala/zio/http/Handler.scala index 08f7a72b2c..52bb0ea89a 100644 --- a/zio-http/src/main/scala/zio/http/Handler.scala +++ b/zio-http/src/main/scala/zio/http/Handler.scala @@ -586,7 +586,7 @@ sealed trait Handler[-R, +Err, -In, +Out] { self => * the handler has been appropriately sandboxed, turning all possible failures * into well-formed HTTP responses. */ - def toHttpApp(implicit err: Err <:< Response, in: Request <:< In, out: Out <:< Response): HttpApp[R] = { + def toHttpApp(implicit err: Err <:< Response, in: Request <:< In, out: Out <:< Response, trace: Trace): HttpApp[R] = { val handler: Handler[R, Response, Request, Response] = self.asInstanceOf[Handler[R, Response, Request, Response]] diff --git a/zio-http/src/main/scala/zio/http/HttpApp.scala b/zio-http/src/main/scala/zio/http/HttpApp.scala index f6d5ab9cd4..ad4fbec202 100644 --- a/zio-http/src/main/scala/zio/http/HttpApp.scala +++ b/zio-http/src/main/scala/zio/http/HttpApp.scala @@ -58,7 +58,7 @@ final case class HttpApp[-Env](routes: Routes[Env, Response]) * method and path of the specified request. */ def isDefinedAt(request: Request): Boolean = - tree.get(request.method, request.path).nonEmpty + tree(Trace.empty).get(request.method, request.path).nonEmpty /** * Provides the specified environment to the HTTP application, returning a new @@ -115,7 +115,7 @@ final case class HttpApp[-Env](routes: Routes[Env, Response]) /** * Accesses the underlying tree that provides fast dispatch to handlers. */ - def tree: HttpApp.Tree[Env] = { + def tree(implicit trace: Trace): HttpApp.Tree[Env] = { if (_tree eq null) { _tree = HttpApp.Tree.fromRoutes(routes) } @@ -150,10 +150,10 @@ object HttpApp { final def ++[Env1 <: Env](that: Tree[Env1]): Tree[Env1] = Tree(self.tree ++ that.tree) - final def add[Env1 <: Env](route: Route[Env1, Response]): Tree[Env1] = + final def add[Env1 <: Env](route: Route[Env1, Response])(implicit trace: Trace): Tree[Env1] = Tree(self.tree.add(route.routePattern, route.toHandler)) - final def addAll[Env1 <: Env](routes: Iterable[Route[Env1, Response]]): Tree[Env1] = + final def addAll[Env1 <: Env](routes: Iterable[Route[Env1, Response]])(implicit trace: Trace): Tree[Env1] = Tree(self.tree.addAll(routes.map(r => (r.routePattern, r.toHandler)))) final def get(method: Method, path: Path): Chunk[RequestHandler[Env, Response]] = @@ -162,7 +162,7 @@ object HttpApp { private[http] object Tree { val empty: Tree[Any] = Tree(RoutePattern.Tree.empty) - def fromRoutes[Env](routes: Routes[Env, Response]): Tree[Env] = + def fromRoutes[Env](routes: Routes[Env, Response])(implicit trace: Trace): Tree[Env] = empty.addAll(routes.routes) } } diff --git a/zio-http/src/main/scala/zio/http/Route.scala b/zio-http/src/main/scala/zio/http/Route.scala index e67a709168..0e0ec8334e 100644 --- a/zio-http/src/main/scala/zio/http/Route.scala +++ b/zio-http/src/main/scala/zio/http/Route.scala @@ -16,6 +16,7 @@ package zio.http import zio._ +import zio.stacktracer.TracingImplicits.disableAutoTrace import zio.http.Route.Provided @@ -40,7 +41,7 @@ sealed trait Route[-Env, +Err] { self => * call this function when you have handled all errors produced by the route, * converting them into responses. */ - final def apply(request: Request)(implicit ev: Err <:< Response): ZIO[Env, Response, Response] = + final def apply(request: Request)(implicit ev: Err <:< Response, trace: Trace): ZIO[Env, Response, Response] = toHandler.apply(request) def asErrorType[Err2](implicit ev: Err <:< Err2): Route[Env, Err2] = self.asInstanceOf[Route[Env, Err2]] @@ -49,14 +50,14 @@ sealed trait Route[-Env, +Err] { self => * Handles the error of the route. This method can be used to convert a route * that does not handle its errors into one that does handle its errors. */ - final def handleError(f: Err => Response): Route[Env, Nothing] = + final def handleError(f: Err => Response)(implicit trace: Trace): Route[Env, Nothing] = self.handleErrorCause(Response.fromCauseWith(_)(f)) /** * Handles the error of the route. This method can be used to convert a route * that does not handle its errors into one that does handle its errors. */ - final def handleErrorCause(f: Cause[Err] => Response): Route[Env, Nothing] = + final def handleErrorCause(f: Cause[Err] => Response)(implicit trace: Trace): Route[Env, Nothing] = self match { case Provided(route, env) => Provided(route.handleErrorCause(f), env) case Augmented(route, aspect) => Augmented(route.handleErrorCause(f), aspect) @@ -107,10 +108,10 @@ sealed trait Route[-Env, +Err] { self => * using best-effort heuristics to determine the appropriate HTTP status code, * and attaching error details using the HTTP header `Warning`. */ - final def sandbox: Route[Env, Nothing] = + final def sandbox(implicit trace: Trace): Route[Env, Nothing] = handleErrorCause(Response.fromCause(_)) - def toHandler(implicit ev: Err <:< Response): Handler[Env, Response, Request, Response] + def toHandler(implicit ev: Err <:< Response, trace: Trace): Handler[Env, Response, Request, Response] final def toHttpApp(implicit ev: Err <:< Response): HttpApp[Env] = Routes(self).toHttpApp @@ -223,7 +224,7 @@ object Route { def routePattern: RoutePattern[_] = route.routePattern - override def toHandler(implicit ev: Err <:< Response): Handler[Any, Response, Request, Response] = + override def toHandler(implicit ev: Err <:< Response, trace: Trace): Handler[Any, Response, Request, Response] = route.toHandler.provideEnvironment(env) override def toString() = s"Route.Provided(${route}, ${env})" @@ -237,7 +238,7 @@ object Route { def routePattern: RoutePattern[_] = route.routePattern - override def toHandler(implicit ev: Err <:< Response): Handler[OutEnv, Response, Request, Response] = + override def toHandler(implicit ev: Err <:< Response, trace: Trace): Handler[OutEnv, Response, Request, Response] = aspect(route.toHandler) override def toString() = s"Route.Augmented(${route}, ${aspect})" @@ -248,7 +249,7 @@ object Route { handler: Handler[Env, Response, Request, Response], location: Trace, ) extends Route[Env, Nothing] { - override def toHandler(implicit ev: Nothing <:< Response): Handler[Env, Response, Request, Response] = + override def toHandler(implicit ev: Nothing <:< Response, trace: Trace): Handler[Env, Response, Request, Response] = handler override def toString() = s"Route.Handled(${routePattern}, ${location})" @@ -262,7 +263,7 @@ object Route { def routePattern = rpm.routePattern - override def toHandler(implicit ev: Err <:< Response): Handler[Env, Response, Request, Response] = { + override def toHandler(implicit ev: Err <:< Response, trace: Trace): Handler[Env, Response, Request, Response] = { convert(handler.asErrorType[Response]) } @@ -270,7 +271,7 @@ object Route { private def convert[Env1 <: Env]( handler: Handler[Env1, Response, Input, Response], - ): Handler[Env1, Response, Request, Response] = { + )(implicit trace: Trace): Handler[Env1, Response, Request, Response] = { implicit val z = zippable Route.handled(rpm)(handler).toHandler diff --git a/zio-http/src/main/scala/zio/http/Routes.scala b/zio-http/src/main/scala/zio/http/Routes.scala index b56e9abf1c..bc8845d1d1 100644 --- a/zio-http/src/main/scala/zio/http/Routes.scala +++ b/zio-http/src/main/scala/zio/http/Routes.scala @@ -16,6 +16,7 @@ package zio.http import zio._ +import zio.stacktracer.TracingImplicits.disableAutoTrace /** * Represents a collection of routes, each of which is defined by a pattern and @@ -65,14 +66,14 @@ final class Routes[-Env, +Err] private (val routes: Chunk[zio.http.Route[Env, Er /** * Handles all typed errors in the routes by converting them into responses. */ - def handleError(f: Err => Response): Routes[Env, Nothing] = + def handleError(f: Err => Response)(implicit trace: Trace): Routes[Env, Nothing] = new Routes(routes.map(_.handleError(f))) /** * Handles all typed errors, as well as all non-recoverable errors, by * converting them into responses. */ - def handleErrorCause(f: Cause[Err] => Response): Routes[Env, Nothing] = + def handleErrorCause(f: Cause[Err] => Response)(implicit trace: Trace): Routes[Env, Nothing] = new Routes(routes.map(_.handleErrorCause(f))) /** @@ -87,14 +88,14 @@ final class Routes[-Env, +Err] private (val routes: Chunk[zio.http.Route[Env, Er * responses, using best-effort heuristics to determine the appropriate HTTP * status code, and attaching error details using the HTTP header `Warning`. */ - def sandbox: Routes[Env, Nothing] = + def sandbox(implicit trace: Trace): Routes[Env, Nothing] = new Routes(routes.map(_.sandbox)) /** * Returns new routes that are all timed out by the specified maximum * duration. */ - def timeout(duration: Duration): Routes[Env, Err] = + def timeout(duration: Duration)(implicit trace: Trace): Routes[Env, Err] = self @@ Middleware.timeout(duration) /** @@ -136,6 +137,6 @@ object Routes { * Constructs a singleton route from a handler that handles all possible * methods and paths. You would only use this method for testing. */ - def singleton[Env, Err](h: Handler[Env, Err, (Path, Request), Response]): Routes[Env, Err] = + def singleton[Env, Err](h: Handler[Env, Err, (Path, Request), Response])(implicit trace: Trace): Routes[Env, Err] = Routes(Route.route(RoutePattern.any)(h)) } diff --git a/zio-http/src/main/scala/zio/http/ZClient.scala b/zio-http/src/main/scala/zio/http/ZClient.scala index 91df9c244a..477ee85cc9 100644 --- a/zio-http/src/main/scala/zio/http/ZClient.scala +++ b/zio-http/src/main/scala/zio/http/ZClient.scala @@ -80,7 +80,7 @@ final case class ZClient[-Env, -In, +Err, +Out]( def addUrl(url: URL): ZClient[Env, In, Err, Out] = copy(url = self.url ++ url) - def contramap[In2](f: In2 => In): ZClient[Env, In2, Err, Out] = + def contramap[In2](f: In2 => In)(implicit trace: Trace): ZClient[Env, In2, Err, Out] = contramapZIO(in => ZIO.succeed(f(in))) def contramapZIO[Env1 <: Env, Err1 >: Err, In2](f: In2 => ZIO[Env1, Err1, In]): ZClient[Env1, In2, Err1, Out] = @@ -90,7 +90,7 @@ final case class ZClient[-Env, -In, +Err, +Out]( self.driver, ) - def delete(suffix: String)(implicit ev: Body <:< In): ZIO[Env & Scope, Err, Out] = + def delete(suffix: String)(implicit ev: Body <:< In, trace: Trace): ZIO[Env & Scope, Err, Out] = request(Method.DELETE, suffix)(ev(Body.empty)) def dieOn( @@ -98,26 +98,26 @@ final case class ZClient[-Env, -In, +Err, +Out]( )(implicit ev1: Err IsSubtypeOfError Throwable, ev2: CanFail[Err], trace: Trace): ZClient[Env, In, Err, Out] = refineOrDie { case e if !f(e) => e } - def disableStreaming(implicit ev: Err <:< Throwable): ZClient[Env, In, Throwable, Out] = + def disableStreaming(implicit ev: Err <:< Throwable, trace: Trace): ZClient[Env, In, Throwable, Out] = transform(bodyEncoder.widenError[Throwable], bodyDecoder.widenError[Throwable], driver.disableStreaming) - def get(suffix: String)(implicit ev: Body <:< In): ZIO[Env & Scope, Err, Out] = + def get(suffix: String)(implicit ev: Body <:< In, trace: Trace): ZIO[Env & Scope, Err, Out] = request(Method.GET, suffix)(ev(Body.empty)) - def head(suffix: String)(implicit ev: Body <:< In): ZIO[Env & Scope, Err, Out] = + def head(suffix: String)(implicit ev: Body <:< In, trace: Trace): ZIO[Env & Scope, Err, Out] = request(Method.HEAD, suffix)(ev(Body.empty)) def host(host: String): ZClient[Env, In, Err, Out] = copy(url = url.host(host)) - def map[Out2](f: Out => Out2): ZClient[Env, In, Err, Out2] = + def map[Out2](f: Out => Out2)(implicit trace: Trace): ZClient[Env, In, Err, Out2] = mapZIO(out => ZIO.succeed(f(out))) def mapError[Err2](f: Err => Err2): ZClient[Env, In, Err2, Out] = transform( bodyEncoder.mapError(f), new ZClient.BodyDecoder[Env, Err2, Out] { - def decode(response: Response): ZIO[Env, Err2, Out] = + def decode(response: Response)(implicit trace: Trace): ZIO[Env, Err2, Out] = self.bodyDecoder.decode(response).mapError(f) }, driver.mapError(f), @@ -135,7 +135,7 @@ final case class ZClient[-Env, -In, +Err, +Out]( def path(path: Path): ZClient[Env, In, Err, Out] = copy(url = url.copy(path = path)) - def patch(suffix: String)(implicit ev: Body <:< In): ZIO[Env & Scope, Err, Out] = + def patch(suffix: String)(implicit ev: Body <:< In, trace: Trace): ZIO[Env & Scope, Err, Out] = request(Method.PATCH, suffix)(ev(Body.empty)) def port(port: Int): ZClient[Env, In, Err, Out] = @@ -152,7 +152,7 @@ final case class ZClient[-Env, -In, +Err, +Out]( )(implicit ev1: Err IsSubtypeOfError Throwable, ev2: CanFail[Err], trace: Trace): ZClient[Env, In, Err2, Out] = transform(bodyEncoder.refineOrDie(pf), bodyDecoder.refineOrDie(pf), driver.refineOrDie(pf)) - def request(request: Request)(implicit ev: Body <:< In): ZIO[Env & Scope, Err, Out] = + def request(request: Request)(implicit ev: Body <:< In, trace: Trace): ZIO[Env & Scope, Err, Out] = if (bodyEncoder == ZClient.BodyEncoder.identity) bodyDecoder.decodeZIO( driver @@ -251,7 +251,7 @@ object ZClient { def configured( path: NonEmptyChunk[String] = NonEmptyChunk("zio", "http", "client"), - ): ZLayer[DnsResolver, Throwable, Client] = + )(implicit trace: Trace): ZLayer[DnsResolver, Throwable, Client] = ( ZLayer.service[DnsResolver] ++ ZLayer(ZIO.config(Config.config.nested(path.head, path.tail: _*))) ++ @@ -298,33 +298,36 @@ object ZClient { (NettyClientDriver.live ++ ZLayer.service[DnsResolver]) >>> customized }.fresh - def request(request: Request): ZIO[Client & Scope, Throwable, Response] = + def request(request: Request)(implicit trace: Trace): ZIO[Client & Scope, Throwable, Response] = ZIO.serviceWithZIO[Client](c => c(request)) - def socket[R](socketApp: WebSocketApp[R]): ZIO[R with Client & Scope, Throwable, Response] = + def socket[R](socketApp: WebSocketApp[R])(implicit trace: Trace): ZIO[R with Client & Scope, Throwable, Response] = ZIO.serviceWithZIO[Client](c => c.socket(socketApp)) trait BodyDecoder[-Env, +Err, +Out] { self => - def decode(response: Response): ZIO[Env, Err, Out] + def decode(response: Response)(implicit trace: Trace): ZIO[Env, Err, Out] - def decodeZIO[Env1 <: Env, Err1 >: Err](zio: ZIO[Env1, Err1, Response]): ZIO[Env1, Err1, Out] = + def decodeZIO[Env1 <: Env, Err1 >: Err](zio: ZIO[Env1, Err1, Response])(implicit + trace: Trace, + ): ZIO[Env1, Err1, Out] = zio.flatMap(decode) final def mapError[Err2](f: Err => Err2): BodyDecoder[Env, Err2, Out] = new BodyDecoder[Env, Err2, Out] { - def decode(response: Response): ZIO[Env, Err2, Out] = self.decode(response).mapError(f) + def decode(response: Response)(implicit trace: Trace): ZIO[Env, Err2, Out] = self.decode(response).mapError(f) } final def mapZIO[Env1 <: Env, Err1 >: Err, Out2](f: Out => ZIO[Env1, Err1, Out2]): BodyDecoder[Env1, Err1, Out2] = new BodyDecoder[Env1, Err1, Out2] { - def decode(response: Response): ZIO[Env1, Err1, Out2] = self.decode(response).flatMap(f) + def decode(response: Response)(implicit trace: Trace): ZIO[Env1, Err1, Out2] = self.decode(response).flatMap(f) } final def refineOrDie[Err2]( pf: PartialFunction[Err, Err2], )(implicit ev1: Err IsSubtypeOfError Throwable, ev2: CanFail[Err], trace: Trace): BodyDecoder[Env, Err2, Out] = new BodyDecoder[Env, Err2, Out] { - def decode(response: Response): ZIO[Env, Err2, Out] = self.decode(response).refineOrDie(pf) + def decode(response: Response)(implicit trace: Trace): ZIO[Env, Err2, Out] = + self.decode(response).refineOrDie(pf) } final def widenError[E1](implicit ev: Err <:< E1): BodyDecoder[Env, E1, Out] = @@ -333,32 +336,33 @@ object ZClient { object BodyDecoder { val identity: BodyDecoder[Any, Nothing, Response] = new BodyDecoder[Any, Nothing, Response] { - final def decode(response: Response): ZIO[Any, Nothing, Response] = Exit.succeed(response) + final def decode(response: Response)(implicit trace: Trace): ZIO[Any, Nothing, Response] = + Exit.succeed(response) override def decodeZIO[Env1 <: Any, Err1 >: Nothing]( zio: ZIO[Env1, Err1, Response], - ): ZIO[Env1, Err1, Response] = + )(implicit trace: Trace): ZIO[Env1, Err1, Response] = zio } } trait BodyEncoder[-Env, +Err, -In] { self => final def contramapZIO[Env1 <: Env, Err1 >: Err, In2](f: In2 => ZIO[Env1, Err1, In]): BodyEncoder[Env1, Err1, In2] = new BodyEncoder[Env1, Err1, In2] { - def encode(in: In2): ZIO[Env1, Err1, Body] = f(in).flatMap(self.encode) + def encode(in: In2)(implicit trace: Trace): ZIO[Env1, Err1, Body] = f(in).flatMap(self.encode) } - def encode(in: In): ZIO[Env, Err, Body] + def encode(in: In)(implicit trace: Trace): ZIO[Env, Err, Body] final def mapError[Err2](f: Err => Err2): BodyEncoder[Env, Err2, In] = new BodyEncoder[Env, Err2, In] { - def encode(in: In): ZIO[Env, Err2, Body] = self.encode(in).mapError(f) + def encode(in: In)(implicit trace: Trace): ZIO[Env, Err2, Body] = self.encode(in).mapError(f) } final def refineOrDie[Err2]( pf: PartialFunction[Err, Err2], )(implicit ev1: Err IsSubtypeOfError Throwable, ev2: CanFail[Err], trace: Trace): BodyEncoder[Env, Err2, In] = new BodyEncoder[Env, Err2, In] { - def encode(in: In): ZIO[Env, Err2, Body] = self.encode(in).refineOrDie(pf) + def encode(in: In)(implicit trace: Trace): ZIO[Env, Err2, Body] = self.encode(in).refineOrDie(pf) } final def widenError[E1](implicit ev: Err <:< E1): BodyEncoder[Env, E1, In] = @@ -367,7 +371,7 @@ object ZClient { object BodyEncoder { val identity: BodyEncoder[Any, Nothing, Body] = new BodyEncoder[Any, Nothing, Body] { - def encode(body: Body): ZIO[Any, Nothing, Body] = Exit.succeed(body) + def encode(body: Body)(implicit trace: Trace): ZIO[Any, Nothing, Body] = Exit.succeed(body) } }