-
-
Notifications
You must be signed in to change notification settings - Fork 83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to catch exceptions? #543
Comments
If I understand correctly, you are looking for a way to handle exceptions systematically throughout your app. Have you looked into accomplishing this with a ZTransform similar to the one here: https://scalapb.github.io/zio-grpc/docs/next/decorating |
here is a better version of my sample using the samples in the repo: package zio_grpc.examples.helloworld
import io.grpc.StatusException
import scalapb.zio_grpc.ServerMain
import scalapb.zio_grpc.ServiceList
import zio._
import zio.Console._
import io.grpc.examples.helloworld.helloworld.ZioHelloworld.Greeter
import io.grpc.examples.helloworld.helloworld.{HelloReply, HelloRequest}
import io.grpc.StatusException
import scalapb.zio_grpc.{RequestContext, ZTransform}
import zio._
import zio.stream.ZStream
class LoggingTransform extends ZTransform[Any, RequestContext] {
def logCause(rc: RequestContext, cause: Cause[StatusException]): UIO[Unit] =
printLine(rc.toString()).orDie
def accessLog(rc: RequestContext): UIO[Unit] = {
printLine(rc.toString()).orDie
}
override def effect[A](
io: Any => ZIO[Any, StatusException, A]
): RequestContext => ZIO[Any, StatusException, A] = { rc =>
io(rc).zipLeft(accessLog(rc)).tapErrorCause(logCause(rc, _))
}
override def stream[A](
io: Any => ZStream[Any, StatusException, A]
): RequestContext => ZStream[Any, StatusException, A] = { rc =>
(io(rc) ++ ZStream.fromZIO(accessLog(rc)).drain).onError(logCause(rc, _))
}
}
object GreeterImpl extends Greeter {
def parse(value: String) = {
value match {
case "test" => ???
case "fail" =>
ZIO.fail(new StatusException(io.grpc.Status.INVALID_ARGUMENT))
case _ =>
ZIO.succeed(HelloReply(s"Parsed, ${value}"))
}
}
def sayHello(
request: HelloRequest
): ZIO[Any, StatusException, HelloReply] = {
parse(request.name).logError("errr") *> printLine(
s"Got request: $request"
).orDie zipRight
ZIO.succeed(HelloReply(s"Hello, ${request.name}"))
}
}
object HelloWorldServer extends ServerMain {
val decoratedService =
GreeterImpl.transform(new LoggingTransform)
def services: ServiceList[Any] = ServiceList.add(decoratedService)
} @thesamet I tested with and without transform. basically there is no way to log non-zio exceptions. In a simple Zio code you get an exception in the console. In Akka or other places, we get the exception in the console or logs and server continue to work. Is my question more clear now? |
I'd like to investigate more on what would be a consistent behavior with other ZIO libraries, however in the meantime, if you expect your effects might throw exception maybe the transformer can catch, handle and convert them to values:
|
yep, this does the job:
|
Nice. This probably gives reasonable coverage for most people but it's
worth noting that few cases will not be caught, for instance if `io(rc)`
returns null or an object that's not a `ZIO`. Those would be passed through
and trigger the error outside the `try{}`
…On Thu, Aug 17, 2023 at 8:48 AM Omid Bakhshandeh ***@***.***> wrote:
yep, this does the job:
override def effect[A](
io: Any => ZIO[Any, StatusException, A]
): RequestContext => ZIO[Any, StatusException, A] = { rc =>
try { io(rc) }
catch {
case t: Throwable =>
(ZIO.logError(t.getMessage()) *> ZIO.fail(t)).mapError { t =>
new StatusException(Status.INTERNAL)
}
}
}
—
Reply to this email directly, view it on GitHub
<#543 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AACLBLOL3JMM4XL5NCXUIHDXVY4OHANCNFSM6AAAAAA3RW2OYY>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
--
-Nadav
|
@thesamet it would be great to have a catch all to at least be able to log everything |
I have a ZIO grpc server running and somewhere in my code there is an
???
unimplemented exception. I get nowcause
or anything in my call and I cannot log the error or cause. Using the debugger I see that it ends up in here:zio-grpc/core/src/main/scalajvm/scalapb/zio_grpc/server/ListenerDriver.scala
Line 32 in 5c3b4b8
of course, wrapping everything in ZIO.attempt bubbles up the error but that is not a good pattern to follow.
What am I missing?
The text was updated successfully, but these errors were encountered: