Skip to content

Commit

Permalink
Add tapErrorZIO and tapErrorCauseZIO to Route and Routes
Browse files Browse the repository at this point in the history
  • Loading branch information
tjarvstrand committed Aug 30, 2024
1 parent b4dde6a commit c45935a
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
65 changes: 65 additions & 0 deletions zio-http/shared/src/main/scala/zio/http/Route.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
*/
package zio.http

import zio.Cause.Fail
import zio._

import zio.http.Route.CheckResponse
import zio.http.codec.PathCodec

/*
Expand Down Expand Up @@ -131,6 +133,57 @@ sealed trait Route[-Env, +Err] { self =>
Handled(rpm.routePattern, handler2, location)
}

/**
* Effectfully peeks at the unhandled failure of this Route.
*/
final def tapErrorZIO[Err1 >: Err](
f: Err => ZIO[Any, Err1, Any],
)(implicit trace: Trace, ev: CheckResponse[Err]): Route[Env, Err1] =
self match {
case Provided(route, env) => Provided(route.tapErrorZIO(f), env)
case Augmented(route, aspect) => Augmented(route.tapErrorZIO(f), aspect)
case Handled(routePattern, handler, location) =>
Handled(
routePattern,
if (ev.isResponse) {
handler.map(_.tapErrorCauseZIO {
case err: Fail[_] =>
f(err.value.asInstanceOf[Err]).catchAllCause(cause => ZIO.fail(Response.fromCause(cause)))
case _ =>
ZIO.unit
})
} else handler,
location,
)
case Unhandled(rpm, handler, zippable, location) => Unhandled(rpm, handler.tapErrorZIO(f), zippable, location)
}

/**
* Effectfully peeks at the unhandled failure cause of this Route.
*/
final def tapErrorCauseZIO[Err1 >: Err](
f: Cause[Err] => ZIO[Any, Err1, Any],
)(implicit trace: Trace, ev: CheckResponse[Err]): Route[Env, Err1] =
self match {
case Provided(route, env) => Provided(route.tapErrorCauseZIO(f), env)
case Augmented(route, aspect) => Augmented(route.tapErrorCauseZIO(f), aspect)
case Handled(routePattern, handler, location) =>
Handled(
routePattern,
handler.map(_.tapErrorCauseZIO {
case cause0 if ev.isResponse =>
f(cause0.asInstanceOf[Cause[Err]]).catchAllCause(cause => ZIO.fail(Response.fromCause(cause)))
case _: Fail[_] =>
ZIO.unit
case cause0 =>
f(cause0.asInstanceOf[Cause[Nothing]]).catchAllCause(cause => ZIO.fail(Response.fromCause(cause)))
}),
location,
)
case Unhandled(rpm, handler, zippable, location) =>
Unhandled(rpm, handler.tapErrorCauseZIO(f), zippable, location)
}

/**
* Allows the transformation of the Err type through a function allowing one
* to build up a Routes in Stages targets the Unhandled case
Expand Down Expand Up @@ -489,4 +542,16 @@ object Route {
}
}

sealed trait CheckResponse[-A] { def isResponse: Boolean }
object CheckResponse {
implicit val response: CheckResponse[Response] = new CheckResponse[Response] {
val isResponse = true
}

// to avoid unnecessary allocation
private val otherInstance: CheckResponse[Nothing] = new CheckResponse[Nothing] {
val isResponse = false
}
implicit def other[A]: CheckResponse[A] = otherInstance.asInstanceOf[CheckResponse[A]]
}
}
12 changes: 12 additions & 0 deletions zio-http/shared/src/main/scala/zio/http/Routes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,18 @@ final case class Routes[-Env, +Err](routes: Chunk[zio.http.Route[Env, Err]]) { s
def handleErrorCauseZIO(f: Cause[Err] => ZIO[Any, Nothing, Response])(implicit trace: Trace): Routes[Env, Nothing] =
new Routes(routes.map(_.handleErrorCauseZIO(f)))

/**
* Effectfully peeks at the unhandled failure of this Routes.
*/
def tapErrorZIO[Err1 >: Err](f: Err => ZIO[Any, Err1, Any])(implicit trace: Trace): Routes[Env, Err1] =
new Routes(routes.map(_.tapErrorZIO(f)))

/**
* Effectfully peeks at the unhandled failure cause of this Routes.
*/
def tapErrorCauseZIO[Err1 >: Err](f: Cause[Err] => ZIO[Any, Err1, Any])(implicit trace: Trace): Routes[Env, Err1] =
new Routes(routes.map(_.tapErrorCauseZIO(f)))

/**
* Allows the transformation of the Err type through an Effectful program
* allowing one to build up Routes in Stages delegates to the Route.
Expand Down

0 comments on commit c45935a

Please sign in to comment.