Skip to content

Commit

Permalink
Add missing traces to the http package (#2354)
Browse files Browse the repository at this point in the history
  • Loading branch information
jaliss authored Sep 24, 2023
1 parent 06014f5 commit 798c17f
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 45 deletions.
2 changes: 1 addition & 1 deletion zio-http/src/main/scala/zio/http/Handler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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]]

Expand Down
10 changes: 5 additions & 5 deletions zio-http/src/main/scala/zio/http/HttpApp.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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]] =
Expand All @@ -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)
}
}
21 changes: 11 additions & 10 deletions zio-http/src/main/scala/zio/http/Route.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package zio.http

import zio._
import zio.stacktracer.TracingImplicits.disableAutoTrace

import zio.http.Route.Provided

Expand All @@ -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]]
Expand All @@ -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)
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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})"
Expand All @@ -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})"
Expand All @@ -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})"
Expand All @@ -262,15 +263,15 @@ 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])
}

override def toString() = s"Route.Unhandled(${routePattern}, ${location})"

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
Expand Down
11 changes: 6 additions & 5 deletions zio-http/src/main/scala/zio/http/Routes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)))

/**
Expand All @@ -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)

/**
Expand Down Expand Up @@ -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))
}
52 changes: 28 additions & 24 deletions zio-http/src/main/scala/zio/http/ZClient.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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] =
Expand All @@ -90,34 +90,34 @@ 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(
f: Err => Boolean,
)(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),
Expand All @@ -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] =
Expand All @@ -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
Expand Down Expand Up @@ -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: _*))) ++
Expand Down Expand Up @@ -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] =
Expand All @@ -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] =
Expand All @@ -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)
}
}

Expand Down

0 comments on commit 798c17f

Please sign in to comment.